github.com/searKing/golang/go@v1.2.117/exp/slices/sort_test.go (about)

     1  // Copyright 2022 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package slices_test
     6  
     7  import (
     8  	"cmp"
     9  	"slices"
    10  	"strconv"
    11  	"strings"
    12  	"testing"
    13  
    14  	math_ "github.com/searKing/golang/go/exp/math"
    15  	slices_ "github.com/searKing/golang/go/exp/slices"
    16  )
    17  
    18  func TestLinearSearch(t *testing.T) {
    19  	str1 := []string{"foo"}
    20  	str2 := []string{"ab", "ca"}
    21  	str3 := []string{"mo", "qo", "vo"}
    22  	str4 := []string{"ab", "ad", "ca", "xy"}
    23  
    24  	// slice with repeating elements
    25  	strRepeats := []string{"ba", "ca", "da", "da", "da", "ka", "ma", "ma", "ta"}
    26  
    27  	// slice with all element equal
    28  	strSame := []string{"xx", "xx", "xx"}
    29  
    30  	tests := []struct {
    31  		data      []string
    32  		target    string
    33  		wantPos   int
    34  		wantFound bool
    35  	}{
    36  		{[]string{}, "foo", 0, false},
    37  		{[]string{}, "", 0, false},
    38  
    39  		{str1, "foo", 0, true},
    40  		{str1, "bar", 0, false},
    41  		{str1, "zx", 1, false},
    42  
    43  		{str2, "aa", 0, false},
    44  		{str2, "ab", 0, true},
    45  		{str2, "ad", 1, false},
    46  		{str2, "ca", 1, true},
    47  		{str2, "ra", 2, false},
    48  
    49  		{str3, "bb", 0, false},
    50  		{str3, "mo", 0, true},
    51  		{str3, "nb", 1, false},
    52  		{str3, "qo", 1, true},
    53  		{str3, "tr", 2, false},
    54  		{str3, "vo", 2, true},
    55  		{str3, "xr", 3, false},
    56  
    57  		{str4, "aa", 0, false},
    58  		{str4, "ab", 0, true},
    59  		{str4, "ac", 1, false},
    60  		{str4, "ad", 1, true},
    61  		{str4, "ax", 2, false},
    62  		{str4, "ca", 2, true},
    63  		{str4, "cc", 3, false},
    64  		{str4, "dd", 3, false},
    65  		{str4, "xy", 3, true},
    66  		{str4, "zz", 4, false},
    67  
    68  		{strRepeats, "da", 2, true},
    69  		{strRepeats, "db", 5, false},
    70  		{strRepeats, "ma", 6, true},
    71  		{strRepeats, "mb", 8, false},
    72  
    73  		{strSame, "xx", 0, true},
    74  		{strSame, "ab", 0, false},
    75  		{strSame, "zz", 3, false},
    76  	}
    77  	for _, tt := range tests {
    78  		t.Run(tt.target, func(t *testing.T) {
    79  			{
    80  				pos, found := slices_.LinearSearch(tt.data, tt.target)
    81  				if pos != tt.wantPos || found != tt.wantFound {
    82  					t.Errorf("LinearSearch got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound)
    83  				}
    84  				wantPos, wantFound := slices.BinarySearch(tt.data, tt.target)
    85  				if pos != wantPos || found != wantFound {
    86  					t.Errorf("LinearSearch got (%v, %v), BinarySearch want (%v, %v)", pos, found, wantPos, wantFound)
    87  				}
    88  			}
    89  
    90  			{
    91  				pos, found := slices_.LinearSearchFunc(tt.data, tt.target, strings.Compare)
    92  				if pos != tt.wantPos || found != tt.wantFound {
    93  					t.Errorf("LinearSearchFunc got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound)
    94  				}
    95  				wantPos, wantFound := slices.BinarySearchFunc(tt.data, tt.target, strings.Compare)
    96  				if pos != wantPos || found != wantFound {
    97  					t.Errorf("LinearSearch got (%v, %v), BinarySearchFunc want (%v, %v)", pos, found, wantPos, wantFound)
    98  				}
    99  			}
   100  		})
   101  	}
   102  }
   103  
   104  func TestLinearSearchInts(t *testing.T) {
   105  	tests := []struct {
   106  		data      []int
   107  		target    int
   108  		wantPos   int
   109  		wantFound bool
   110  	}{
   111  		{nil, 20, 0, false},
   112  		{[]int{}, 20, 0, false},
   113  		{[]int{20, 20, 30, 30}, 20, 0, true},
   114  		{[]int{20, 20, 30, 30}, 23, 2, false},
   115  		{[]int{20, 20, 30, 30}, 30, 2, true},
   116  		{[]int{20, 20, 30, 30}, 43, 4, false},
   117  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 20, 0, true},
   118  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 23, 1, false},
   119  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 43, 3, false},
   120  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 80, 6, true},
   121  	}
   122  	for _, tt := range tests {
   123  		t.Run(strconv.Itoa(tt.target), func(t *testing.T) {
   124  			{
   125  				pos, found := slices_.LinearSearch(tt.data, tt.target)
   126  				if pos != tt.wantPos || found != tt.wantFound {
   127  					t.Errorf("LinearSearch got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound)
   128  				}
   129  				wantPos, wantFound := slices.BinarySearch(tt.data, tt.target)
   130  				if pos != wantPos || found != wantFound {
   131  					t.Errorf("LinearSearch got (%v, %v), BinarySearch want (%v, %v)", pos, found, wantPos, wantFound)
   132  				}
   133  			}
   134  
   135  			{
   136  				compare := cmp.Compare[int]
   137  				pos, found := slices_.LinearSearchFunc(tt.data, tt.target, compare)
   138  				if pos != tt.wantPos || found != tt.wantFound {
   139  					t.Errorf("LinearSearchFunc got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound)
   140  				}
   141  				wantPos, wantFound := slices.BinarySearchFunc(tt.data, tt.target, compare)
   142  				if pos != wantPos || found != wantFound {
   143  					t.Errorf("LinearSearch got (%v, %v), BinarySearchFunc want (%v, %v)", pos, found, wantPos, wantFound)
   144  				}
   145  			}
   146  		})
   147  	}
   148  }
   149  
   150  func TestPartialSortInts(t *testing.T) {
   151  	tests := []struct {
   152  		data []int
   153  		k    int
   154  	}{
   155  		{nil, 3},
   156  		{[]int{}, 3},
   157  		{[]int{20, 20, 30, 30}, 3},
   158  		{[]int{20, 30}, 3},
   159  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 3},
   160  		{[]int{90, 80, 70, 60, 50, 40, 30, 20}, 3},
   161  		{[]int{90, 30, 70, 40, 50, 60, 80, 20}, 3},
   162  	}
   163  	for i, tt := range tests {
   164  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   165  			{
   166  				data1 := slices.Clone(tt.data)
   167  				slices_.PartialSort(data1, tt.k)
   168  				if !slices_.IsPartialSorted(data1, tt.k) {
   169  					t.Errorf("partial sort didn't sort")
   170  				}
   171  			}
   172  
   173  			{
   174  				data2 := slices.Clone(tt.data)
   175  				slices_.PartialSortFunc(data2, tt.k, cmp.Compare[int])
   176  				if !slices_.IsPartialSorted(data2, tt.k) {
   177  					t.Errorf("partial sort func didn't sort")
   178  				}
   179  			}
   180  		})
   181  	}
   182  }
   183  
   184  func TestSearchMin(t *testing.T) {
   185  	tests := []struct {
   186  		data []int
   187  		want int
   188  	}{
   189  		{nil, 0},
   190  		{[]int{}, 0},
   191  		{[]int{20, 20, 30, 30}, 0},
   192  		{[]int{20, 30}, 0},
   193  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 0},
   194  		{[]int{90, 80, 70, 60, 50, 40, 30, 20}, 7},
   195  		{[]int{90, 30, 70, 40, 50, 60, 80, 20}, 7},
   196  		{[]int{90, 30, 70, 40, 50, 60, 80, 20, 100, 30}, 7},
   197  	}
   198  	for i, tt := range tests {
   199  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   200  			{
   201  				got := slices_.SearchMin(tt.data)
   202  				if got != tt.want {
   203  					t.Errorf("SearchMin(%v) got (%v), want (%v)", tt.data, got, tt.want)
   204  				}
   205  			}
   206  			{
   207  				got := slices_.SearchMinFunc(tt.data, cmp.Compare[int])
   208  				if got != tt.want {
   209  					t.Errorf("SearchMinFunc(%v, math_.Compare[int]) got (%v), want (%v)", tt.data, got, tt.want)
   210  				}
   211  			}
   212  		})
   213  	}
   214  }
   215  
   216  func TestSearchMax(t *testing.T) {
   217  	tests := []struct {
   218  		data []int
   219  		want int
   220  	}{
   221  		{nil, 0},
   222  		{[]int{}, 0},
   223  		{[]int{20, 20, 30, 30}, 2},
   224  		{[]int{20, 30}, 1},
   225  		{[]int{20, 30, 40, 50, 60, 70, 80, 90}, 7},
   226  		{[]int{90, 80, 70, 60, 50, 40, 30, 20}, 0},
   227  		{[]int{90, 30, 70, 40, 50, 60, 80, 20}, 0},
   228  		{[]int{90, 30, 70, 40, 50, 60, 80, 20, 100, 30}, 8},
   229  	}
   230  	for i, tt := range tests {
   231  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   232  			{
   233  				got := slices_.SearchMax(tt.data)
   234  				if got != tt.want {
   235  					t.Errorf("SearchMax(%v) got (%v), want (%v)", tt.data, got, tt.want)
   236  				}
   237  			}
   238  			{
   239  				got := slices_.SearchMinFunc(tt.data, math_.Reverse(cmp.Compare[int]))
   240  				if got != tt.want {
   241  					t.Errorf("SearchMinFunc(%v, math_.Reverse(math_.Compare[int])) got (%v), want (%v)", tt.data, got, tt.want)
   242  				}
   243  			}
   244  		})
   245  	}
   246  }