r30_rs/
lib.rs

1mod r30;
2pub use r30::*;
3
4#[cfg(test)]
5mod tests {
6    use crate::*;
7
8    /// Assert that the Automata behaves as expected
9    #[test]
10    fn test_automata_behavior() {
11        // Start with only the center cell active
12        let mut gen = R30::center();
13        // 35 precomputed values
14        const EXPECTED: [u32; 35] = [
15            65536, 229376, 311296, 1007616, 1126400, 3921920, 4738048, 16578048, 17240832,
16            59358592, 81691840, 256036704, 291926320, 993762264, 1237903436, 4269616374, 59107090,
17            80492991, 2406895233, 3507745474, 1539055206, 3364234171, 2110485640, 2222528476,
18            3465523271, 1926273256, 2656693548, 3821938151, 879983672, 1453131340, 3538258934,
19            1581045778, 3276229695, 1701410368, 3173979104,
20        ];
21
22        for i in 0..EXPECTED.len() {
23            assert_eq!(gen.state, EXPECTED[i]);
24            gen.evolve();
25        }
26    }
27
28    /// Monobit frequency test for default implementation
29    #[test]
30    fn monobit_freq() {
31        let mut gen = R30::default();
32        let mut zero: u64 = 0;
33        let mut one: u64 = 0;
34
35        const BITS: u64 = 1e6 as u64;
36        const EPSILON: f64 = 1e-3;
37
38        for _ in 0..BITS {
39            let bit = gen.next_bool();
40            zero += !bit as u64;
41            one += bit as u64;
42        }
43
44        // Compute P(0) and P(1)
45        let p0 = zero as f64 / BITS as f64;
46        let p1 = one as f64 / BITS as f64;
47        // Get their distances from the Expected value of 0.5
48        let d0 = (p0 - 0.5).abs();
49        let d1 = (p1 - 0.5).abs();
50        // If either is too large the test fails
51        assert!(d0 <= EPSILON);
52        assert!(d1 <= EPSILON);
53    }
54
55    /// Assert that values generated in [a, b] stay in [a, b]
56    #[test]
57    fn test_u64_range() {
58        let mut gen = R30::default();
59
60        const a: u64 = 1;
61        const b: u64 = 100;
62
63        const RUNS: u64 = 1e6 as u64;
64
65        for _ in 0..=RUNS {
66            let y = gen.next_u64_in(a, b);
67            assert!(y >= a && y <= b);
68        }
69    }
70    
71
72}