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