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