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