Test of Randomness - Knuth Shuffle

Test of Randomness using a fixed seed. A fixed seed will generate fixed sequence of random numbers.

shuffle.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package shuffle

import (
	"math/rand"
)

// Shuffle - Knuth Shuffle
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
// > -- To shuffle an array a of n elements (indices 0..n-1):
// > for i from n−1 downto 1 do
// >      j ← random integer such that 0 ≤ j ≤ i
// >      exchange a[j] and a[i]
func Shuffle(cards []byte) {
	for i := len(cards) - 1; i > 0; i-- {
		j := rand.Intn(i + 1)
		cards[i], cards[j] = cards[j], cards[i]
	}
}

// ShuffleClone - Knuth Shuffle in a clone
func ShuffleClone(cards []byte) (clone []byte) {
	// How to perfectly clone a slice
	// https://github.com/go101/go101/wiki/How-to-perfectly-clone-a-slice%3F
	clone = append(cards[:0:0], cards...)
	Shuffle(clone)
	return
}

shuffle_test.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package shuffle

import (
	"math/rand"
	"testing"
)

func TestShuffleClone(t *testing.T) {
	// The fixed seed
	rand.Seed(1024)
	inputs := [][]byte{
		nil,
		[]byte("0"),
		[]byte("0123456789abcdefghijklmnopqrstuvwxyz"),
	}
	outputs := [][]byte{
		nil,
		[]byte("0"),
		[]byte("2rjdbtag3npum408wvxf1s59zy7kqloihce6"),
	}

	for index, input := range inputs {
		output := ShuffleClone(input)
		if string(output) != string(outputs[index]) {
			t.Errorf("ShuffleClone(%s) failed, expected \"%s\", got \"%s\".", string(input), string(outputs[index]), string(output))
		}
	}
}

Test coverage

1
2
3
4
$ go test -cover
PASS
coverage: 100.0% of statements
ok      _/Users/mingjie/Documents/Development/shuffle   0.010s