rand: add `pub fn shuffle<T>(mut a []T) {` function + tests (#13811)
parent
35cd8112a5
commit
2e963e36ac
|
@ -467,3 +467,20 @@ pub fn hex(len int) string {
|
|||
pub fn ascii(len int) string {
|
||||
return string_from_set(rand.ascii_chars, len)
|
||||
}
|
||||
|
||||
// shuffle randomly permutates the elements in `a`.
|
||||
pub fn shuffle<T>(mut a []T) {
|
||||
len := a.len
|
||||
for i in 0 .. len {
|
||||
si := i + intn(len - i) or { len }
|
||||
a[si], a[i] = a[i], a[si]
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle_clone returns a random permutation of the elements in `a`.
|
||||
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
|
||||
pub fn shuffle_clone<T>(a []T) []T {
|
||||
mut res := a.clone()
|
||||
shuffle(mut res)
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -317,3 +317,55 @@ fn test_new_global_rng() {
|
|||
|
||||
rand.set_rng(old)
|
||||
}
|
||||
|
||||
fn test_shuffle() {
|
||||
mut arrays := [][]int{}
|
||||
arrays << [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
arrays << [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
for seed in seeds {
|
||||
a := get_n_random_ints(seed, 10)
|
||||
arrays << a
|
||||
}
|
||||
//
|
||||
mut digits := []map[int]int{len: 10}
|
||||
for digit in 0 .. 10 {
|
||||
digits[digit] = {}
|
||||
for idx in 0 .. 10 {
|
||||
digits[digit][idx] = 0
|
||||
}
|
||||
}
|
||||
for mut a in arrays {
|
||||
o := a.clone()
|
||||
for _ in 0 .. 100 {
|
||||
rand.shuffle(mut a)
|
||||
assert *a != o
|
||||
for idx in 0 .. 10 {
|
||||
digits[idx][a[idx]]++
|
||||
}
|
||||
}
|
||||
}
|
||||
for digit in 1 .. 10 {
|
||||
assert digits[0] != digits[digit]
|
||||
}
|
||||
for digit in 0 .. 10 {
|
||||
for idx in 0 .. 10 {
|
||||
assert digits[digit][idx] > 10
|
||||
}
|
||||
// eprintln('digits[$digit]: ${digits[digit]}')
|
||||
}
|
||||
}
|
||||
|
||||
fn test_shuffle_clone() {
|
||||
original := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
mut a := original.clone()
|
||||
mut results := [][]int{}
|
||||
for _ in 0 .. 10 {
|
||||
results << rand.shuffle_clone(a)
|
||||
}
|
||||
assert original == a
|
||||
for idx in 1 .. 10 {
|
||||
assert results[idx].len == 10
|
||||
assert results[idx] != results[0]
|
||||
assert results[idx] != original
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue