1#[derive(Clone, Copy, Debug, Hash)]
3pub struct Rng64 {
4 state: u64,
5}
6
7impl Rng64 {
8 pub fn new(seed: u64) -> Self {
9 let mut s = seed;
10 if s == 0 {
11 s = 0x9E3779B97F4A7C15;
12 }
13 Self { state: s }
14 }
15
16 pub fn next_u64(&mut self) -> u64 {
17 let mut x = self.state;
19 x ^= x >> 12;
20 x ^= x << 25;
21 x ^= x >> 27;
22 self.state = x;
23 x.wrapping_mul(0x2545F4914F6CDD1D)
24 }
25
26 pub fn next_u32(&mut self) -> u32 {
27 (self.next_u64() >> 32) as u32
28 }
29
30 pub fn state(&self) -> u64 {
31 self.state
32 }
33
34 pub fn next_bool(&mut self) -> bool {
35 (self.next_u64() & 1) == 1
36 }
37
38 pub fn gen_range(&mut self, upper: usize) -> usize {
39 if upper == 0 {
40 return 0;
41 }
42 (self.next_u64() as usize) % upper
43 }
44
45 pub fn shuffle<T>(&mut self, slice: &mut [T]) {
46 for i in (1..slice.len()).rev() {
47 let j = self.gen_range(i + 1);
48 slice.swap(i, j);
49 }
50 }
51}