shuffle.go 1005 B

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