1#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
2pub struct Rng {
3 state: u64,
4}
5
6impl Rng {
7 pub const RAND_MAX: u64 = MODULUS - 1;
8
9 pub fn with_seed(seed: u64) -> Rng {
10 Rng {
11 state: seed % MODULUS,
12 }
13 }
14
15 pub fn forward(&mut self) -> u64 {
18 let here = self.state;
19 self.state = MULTIPLIER.wrapping_mul(self.state).wrapping_add(INCREMENT) % MODULUS;
20 here
21 }
22
23 pub fn backward(&mut self) -> u64 {
24 self.state = INVERSE_MULTIPLIER.wrapping_mul(self.state.wrapping_sub(INCREMENT)) % MODULUS;
26 self.state
27 }
28}
29
30const MULTIPLIER: u64 = 1103515245;
33const INCREMENT: u64 = 12345;
34const MODULUS: u64 = 2147483648;
35const INVERSE_MULTIPLIER: u64 = 1857678181;
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn rng_goes_both_ways() {
43 let mut rng = Rng::with_seed(12304);
44 rng.backward();
45 rng.backward();
46 let forward = std::iter::repeat_with(|| rng.forward())
47 .take(5)
48 .collect::<Vec<_>>();
49 let mut backward = std::iter::repeat_with(|| rng.backward())
50 .take(5)
51 .collect::<Vec<_>>();
52 backward.reverse();
53 assert_eq!(forward, backward);
54 }
55
56 #[test]
57 fn inverse_multiplier_is_correct() {
58 assert!(MULTIPLIER * INVERSE_MULTIPLIER % MODULUS == 1);
59 }
60
61 #[test]
62 fn no_overflow() {
63 let mut rng = Rng::with_seed(17700000001);
64 rng.forward();
65 }
66}