From 8cb84e4daed8b0a689ed169336ca17f0dcdc0c95 Mon Sep 17 00:00:00 2001 From: psampaz Date: Fri, 6 Dec 2019 20:51:29 +0200 Subject: [PATCH] add Shuffle operation (#16) --- CHANGELOG.md | 1 + README.md | 10 +- shuffle.go | 272 ++++++++++ shuffle_test.go | 1326 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1608 insertions(+), 1 deletion(-) create mode 100644 shuffle.go create mode 100644 shuffle_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a2cfc4..cc83ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,4 +16,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Max operation - Min operation - Reverse operation +- Shuffle operation - Sum operation diff --git a/README.md b/README.md index 8a8e91c..f3dd140 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ go get github.com/psampaz/slice | Push | - | - | - | - | - | - | - | - | | Reverse | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | Shift | - | - | - | - | - | - | - | - | -| Shuffle | - | - | - | - | - | - | - | - | +| Shuffle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | Sum | ✕ | ✔ | ✔ | ✔ | ✔ | ✕ | ✔ | ✔ | | Unshift | - | - | - | - | - | - | - | - | @@ -111,6 +111,14 @@ Reverse performs in place reversal of a slice a = slice.ReverseInt(a) // [5, 4, 3, 2, 1] ``` +## slice.Shuffle + +Shuffle shuffles (in place) a slice +```go + a := []int{1, 2, 3, 4, 5} + a = slice.ShuffleInt(a) // [3, 5, 1, 4, 2] (random output) + ``` + ## slice.Sum Sum returns the sum of the values of a slice or an error in case of a nil or empty slice diff --git a/shuffle.go b/shuffle.go new file mode 100644 index 0000000..35f324b --- /dev/null +++ b/shuffle.go @@ -0,0 +1,272 @@ +package slice + +import ( + "math/rand" + "time" +) + +// ShuffleBool shuffles (in place) a bool slice +func ShuffleBool(a []bool) []bool { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleByte shuffles (in place) a byte slice +func ShuffleByte(a []byte) []byte { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleComplex128 shuffles (in place) a complex128 slice +func ShuffleComplex128(a []complex128) []complex128 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleComplex64 shuffles (in place) a complex64 slice +func ShuffleComplex64(a []complex64) []complex64 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleFloat32 shuffles (in place) a float32 slice +func ShuffleFloat32(a []float32) []float32 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleFloat64 shuffles (in place) a float64 slice +func ShuffleFloat64(a []float64) []float64 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleInt shuffles (in place) a int slice +func ShuffleInt(a []int) []int { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleInt16 shuffles (in place) a int16 slice +func ShuffleInt16(a []int16) []int16 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleInt32 shuffles (in place) a int32 slice +func ShuffleInt32(a []int32) []int32 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleInt64 shuffles (in place) a int64 slice +func ShuffleInt64(a []int64) []int64 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleInt8 shuffles (in place) a int8 slice +func ShuffleInt8(a []int8) []int8 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleRune shuffles (in place) a rune slice +func ShuffleRune(a []rune) []rune { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleString shuffles (in place) a string slice +func ShuffleString(a []string) []string { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleUint shuffles (in place) a uint slice +func ShuffleUint(a []uint) []uint { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleUint16 shuffles (in place) a uint16 slice +func ShuffleUint16(a []uint16) []uint16 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleUint32 shuffles (in place) a uint32 slice +func ShuffleUint32(a []uint32) []uint32 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleUint64 shuffles (in place) a uint64 slice +func ShuffleUint64(a []uint64) []uint64 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleUint8 shuffles (in place) a uint8 slice +func ShuffleUint8(a []uint8) []uint8 { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} + +// ShuffleUintptr shuffles (in place) a uintptr slice +func ShuffleUintptr(a []uintptr) []uintptr { + if len(a) <= 1 { + return a + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + r.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + }) + + return a +} diff --git a/shuffle_test.go b/shuffle_test.go new file mode 100644 index 0000000..6cb44ba --- /dev/null +++ b/shuffle_test.go @@ -0,0 +1,1326 @@ +package slice + +import ( + "reflect" + "sort" + "testing" +) + +func TestShuffleBool_LessThan2Elements(t *testing.T) { + type args struct { + a []bool + } + tests := []struct { + name string + args args + want []bool + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []bool{}, + }, + want: []bool{}, + }, + { + name: "one element", + args: args{ + a: []bool{true}, + }, + want: []bool{true}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleBool(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleBool() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleBool_MoreThan2Elements(t *testing.T) { + // start with a sorted slice. Let's assume that false < true for testing purposes. + a := []bool{false, false, false, true, true, true} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]bool, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleBool(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUintptr(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return !shuffled[i] // this will put "false" first and "true" after + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleBool() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleByte_LessThan2Elements(t *testing.T) { + type args struct { + a []byte + } + tests := []struct { + name string + args args + want []byte + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []byte{}, + }, + want: []byte{}, + }, + { + name: "one element", + args: args{ + a: []byte{1}, + }, + want: []byte{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleByte(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleByte() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleByte_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []byte{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]byte, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleByte(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleByte(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleByte() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleComplex128_LessThan2Elements(t *testing.T) { + type args struct { + a []complex128 + } + tests := []struct { + name string + args args + want []complex128 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []complex128{}, + }, + want: []complex128{}, + }, + { + name: "one element", + args: args{ + a: []complex128{1}, + }, + want: []complex128{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleComplex128(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleComplex128() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleComplex128_MoreThan2Elements(t *testing.T) { + // start with a sorted slice. Keep the imaginary part 0 to help with sorting operation later on. + a := []complex128{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]complex128, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleComplex128(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleComplex128(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return real(shuffled[i]) < real(shuffled[j]) + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleComplex128() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleComplex64_LessThan2Elements(t *testing.T) { + type args struct { + a []complex64 + } + tests := []struct { + name string + args args + want []complex64 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []complex64{}, + }, + want: []complex64{}, + }, + { + name: "one element", + args: args{ + a: []complex64{1}, + }, + want: []complex64{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleComplex64(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleComplex64() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleComplex64_MoreThan2Elements(t *testing.T) { + // start with a sorted slice. Keep the imaginary part 0 to help with sorting operation later on. + a := []complex64{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]complex64, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleComplex64(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleComplex64(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return real(shuffled[i]) < real(shuffled[j]) + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleComplex64() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleFloat32_LessThan2Elements(t *testing.T) { + type args struct { + a []float32 + } + tests := []struct { + name string + args args + want []float32 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []float32{}, + }, + want: []float32{}, + }, + { + name: "one element", + args: args{ + a: []float32{1}, + }, + want: []float32{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleFloat32(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleFloat32() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleFloat32_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []float32{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]float32, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleFloat32(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleFloat32(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleFloat32() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleFloat64_LessThan2Elements(t *testing.T) { + type args struct { + a []float64 + } + tests := []struct { + name string + args args + want []float64 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []float64{}, + }, + want: []float64{}, + }, + { + name: "one element", + args: args{ + a: []float64{1}, + }, + want: []float64{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleFloat64(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleFloat64() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleFloat64_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []float64{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + shuffled := ShuffleFloat64(a) + if reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleFloat64() = %v, Shuffled slice should not match the original", shuffled) + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleFloat64() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleInt_LessThan2Elements(t *testing.T) { + type args struct { + a []int + } + tests := []struct { + name string + args args + want []int + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []int{}, + }, + want: []int{}, + }, + { + name: "one element", + args: args{ + a: []int{1}, + }, + want: []int{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleInt(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleInt() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleInt_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []int{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]int, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleInt(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleInt(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleInt() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleInt16_LessThan2Elements(t *testing.T) { + type args struct { + a []int16 + } + tests := []struct { + name string + args args + want []int16 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []int16{}, + }, + want: []int16{}, + }, + { + name: "one element", + args: args{ + a: []int16{1}, + }, + want: []int16{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleInt16(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleInt16() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleInt16_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []int16{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]int16, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleInt16(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleInt16(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleInt16() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleInt32_LessThan2Elements(t *testing.T) { + type args struct { + a []int32 + } + tests := []struct { + name string + args args + want []int32 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []int32{}, + }, + want: []int32{}, + }, + { + name: "one element", + args: args{ + a: []int32{1}, + }, + want: []int32{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleInt32(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleInt32() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleInt32_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []int32{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]int32, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleInt32(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleInt32(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleInt32() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleInt64_LessThan2Elements(t *testing.T) { + type args struct { + a []int64 + } + tests := []struct { + name string + args args + want []int64 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []int64{}, + }, + want: []int64{}, + }, + { + name: "one element", + args: args{ + a: []int64{1}, + }, + want: []int64{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleInt64(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleInt64() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleInt64_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []int64{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]int64, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleInt64(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleInt64(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleInt64() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleInt8_LessThan2Elements(t *testing.T) { + type args struct { + a []int8 + } + tests := []struct { + name string + args args + want []int8 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []int8{}, + }, + want: []int8{}, + }, + { + name: "one element", + args: args{ + a: []int8{1}, + }, + want: []int8{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleInt8(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleInt8() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleInt8_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []int8{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]int8, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleInt8(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleInt8(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleInt8() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleRune_LessThan2Elements(t *testing.T) { + type args struct { + a []rune + } + tests := []struct { + name string + args args + want []rune + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []rune{}, + }, + want: []rune{}, + }, + { + name: "one element", + args: args{ + a: []rune{1}, + }, + want: []rune{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleRune(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleRune() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleRune_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []rune{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]rune, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleRune(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleRune(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleRune() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleString_LessThan2Elements(t *testing.T) { + type args struct { + a []string + } + tests := []struct { + name string + args args + want []string + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []string{}, + }, + want: []string{}, + }, + { + name: "one element", + args: args{ + a: []string{"a"}, + }, + want: []string{"a"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleString(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleString() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleString_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []string{"a", "b", "c", "d", "e", "f"} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]string, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleString(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleString(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleString() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleUint_LessThan2Elements(t *testing.T) { + type args struct { + a []uint + } + tests := []struct { + name string + args args + want []uint + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []uint{}, + }, + want: []uint{}, + }, + { + name: "one element", + args: args{ + a: []uint{1}, + }, + want: []uint{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleUint(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleUint() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleUint_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []uint{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]uint, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleUint(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUint(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleUint() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleUint16_LessThan2Elements(t *testing.T) { + type args struct { + a []uint16 + } + tests := []struct { + name string + args args + want []uint16 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []uint16{}, + }, + want: []uint16{}, + }, + { + name: "one element", + args: args{ + a: []uint16{1}, + }, + want: []uint16{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleUint16(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleUint16() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleUint16_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []uint16{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]uint16, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleUint16(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUint16(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleUint16() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleUint32_LessThan2Elements(t *testing.T) { + type args struct { + a []uint32 + } + tests := []struct { + name string + args args + want []uint32 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []uint32{}, + }, + want: []uint32{}, + }, + { + name: "one element", + args: args{ + a: []uint32{1}, + }, + want: []uint32{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleUint32(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleUint32() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleUint32_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []uint32{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]uint32, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleUint32(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUint32(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleUint32() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleUint64_LessThan2Elements(t *testing.T) { + type args struct { + a []uint64 + } + tests := []struct { + name string + args args + want []uint64 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []uint64{}, + }, + want: []uint64{}, + }, + { + name: "one element", + args: args{ + a: []uint64{1}, + }, + want: []uint64{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleUint64(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleUint64() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleUint64_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []uint64{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]uint64, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleUint64(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUint64(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleUint64() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleUint8_LessThan2Elements(t *testing.T) { + type args struct { + a []uint8 + } + tests := []struct { + name string + args args + want []uint8 + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []uint8{}, + }, + want: []uint8{}, + }, + { + name: "one element", + args: args{ + a: []uint8{1}, + }, + want: []uint8{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleUint8(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleUint8() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleUint8_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []uint8{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]uint8, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleUint8(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUint8(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleUint8() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +} + +func TestShuffleUintptr_LessThan2Elements(t *testing.T) { + type args struct { + a []uintptr + } + tests := []struct { + name string + args args + want []uintptr + }{ + { + name: "nil slice", + args: args{ + a: nil, + }, + want: nil, + }, + { + name: "empty slice", + args: args{ + a: []uintptr{}, + }, + want: []uintptr{}, + }, + { + name: "one element", + args: args{ + a: []uintptr{1}, + }, + want: []uintptr{1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ShuffleUintptr(tt.args.a); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ShuffleUintptr() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestShuffleUintptr_MoreThan2Elements(t *testing.T) { + // start with a sorted slice + a := []uintptr{1, 2, 3, 4, 5} + + // Make sure the shuffled slice elements are in different order that the original slice + original := append(a[:0:0], a...) + different := false + shuffled := make([]uintptr, len(a)) + // This is a fragile test because the result of the shuffling might be exactly the same as the original + // We run the shuffle 100 until until we get the first correct shuffle. + // Todo: find a smarter way to test this + for x := 0; x <= 100; x++ { + shuffled = ShuffleUintptr(a) + if !reflect.DeepEqual(shuffled, original) { + different = true + break + } + } + if different == false { + t.Errorf("ShuffleUintptr(): Shuffled slice should not match the original") + } + // Sort the shuffled slice in order to ensure that its elements are the same + sort.Slice(shuffled, func(i, j int) bool { + return shuffled[i] < shuffled[j] + }) + if !reflect.DeepEqual(shuffled, original) { + t.Errorf("ShuffleUintptr() = %v, Shuffled slice should have the same elements with the original %v", shuffled, original) + } +}