pgregory.net/rand@v1.0.3-0.20230808192358-a0b8ce02f4da/rand_generic.go (about)

     1  // Copyright 2022 Gregory Petrosyan <gregory.petrosyan@gmail.com>
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, v. 2.0. If a copy of the MPL was not distributed with this
     5  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
     6  
     7  //go:build go1.18
     8  
     9  package rand
    10  
    11  import "math"
    12  
    13  // ShuffleSlice pseudo-randomizes the order of the elements of s.
    14  //
    15  // When r is nil, ShuffleSlices uses non-deterministic goroutine-local
    16  // pseudo-random data source, and is safe for concurrent use from multiple goroutines.
    17  func ShuffleSlice[S ~[]E, E any](r *Rand, s S) {
    18  	if r == nil {
    19  		i := len(s) - 1
    20  		for ; i > math.MaxInt32-1; i-- {
    21  			j := int(Uint64n(uint64(i) + 1))
    22  			s[i], s[j] = s[j], s[i]
    23  		}
    24  		for ; i > 0; i-- {
    25  			j := int(Uint32n(uint32(i) + 1))
    26  			s[i], s[j] = s[j], s[i]
    27  		}
    28  	} else {
    29  		i := len(s) - 1
    30  		for ; i > math.MaxInt32-1; i-- {
    31  			j := int(r.Uint64n(uint64(i) + 1))
    32  			s[i], s[j] = s[j], s[i]
    33  		}
    34  		for ; i > 0; i-- {
    35  			j := int(r.Uint32n(uint32(i) + 1))
    36  			s[i], s[j] = s[j], s[i]
    37  		}
    38  	}
    39  }