github.com/chaowen112/go-lib@v0.0.0-20231018124935-124cd26d7cbe/randutils/shuffle.go (about) 1 package randutils 2 3 // Shuffle pseudo-randomizes the order of elements. 4 // n is the number of elements. Shuffle panics if n < 0. 5 // swap swaps the elements with indexes i and j. 6 func Shuffle(n int, swap func(i, j int)) { 7 if n < 0 { 8 panic("invalid argument to Shuffle") 9 } 10 11 // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 12 // Shuffle really ought not be called with n that doesn't fit in 32 bits. 13 // Not only will it take a very long time, but with 2³¹! possible permutations, 14 // there's no way that any PRNG can have a big enough internal state to 15 // generate even a minuscule percentage of the possible permutations. 16 // Nevertheless, the right API signature accepts an int n, so handle it as best we can. 17 i := n - 1 18 for ; i > 1<<31-1-1; i-- { 19 j := int(Uint32n(uint32(i + 1))) 20 swap(i, j) 21 } 22 for ; i > 0; i-- { 23 j := int(Uint32n(uint32(i + 1))) 24 swap(i, j) 25 } 26 }