1use rand::{Rng, random};
2
3const MULTIPLIER_A: i64 = 1103515245;
4const INCREMENT_C: i64 = 12345;
5const DEFAULT_SEED: i64 = 3819201;
6
7pub trait RandomGenerator: Default {
12 fn next(&mut self) -> i32;
14 fn next_range(&mut self, from: i32, to: i32) -> i32;
16
17 fn get_random_from_vec<'a, K>(&mut self, vec: &'a Vec<K>) -> &'a K {
19 vec.get(self.next_range(0, vec.len() as i32) as usize)
20 .unwrap()
21 }
22}
23
24pub struct StandardRandomGenerator;
26
27impl Default for StandardRandomGenerator {
28 fn default() -> Self {
29 StandardRandomGenerator
30 }
31}
32
33impl RandomGenerator for StandardRandomGenerator {
34 fn next(&mut self) -> i32 {
35 random()
36 }
37
38 fn next_range(&mut self, from: i32, to: i32) -> i32 {
39 rand::rng().random_range(from..to)
40 }
41}
42
43pub struct CustomNumberGenerator {
48 seed: i64,
49}
50
51impl Default for CustomNumberGenerator {
52 fn default() -> Self {
53 CustomNumberGenerator::new(DEFAULT_SEED)
54 }
55}
56
57impl RandomGenerator for CustomNumberGenerator {
58 fn next(&mut self) -> i32 {
59 self.seed = (self.seed * MULTIPLIER_A + INCREMENT_C) % (i32::MAX as i64);
60 self.seed as i32
61 }
62
63 fn next_range(&mut self, from: i32, to: i32) -> i32 {
64 (self.next() % (to - from)).abs() + from
65 }
66}
67
68impl CustomNumberGenerator {
69 pub const fn new(seed: i64) -> Self {
71 Self { seed }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use crate::random::{CustomNumberGenerator, RandomGenerator};
78
79 #[test]
80 fn outputs_same_numbers() {
81 let mut crg = CustomNumberGenerator::new(42);
82 assert_eq!(crg.next_range(0, 10), 8);
83 assert_eq!(crg.next_range(0, 10), 4);
84 assert_eq!(crg.next_range(0, 10), 1);
85 assert_eq!(crg.next_range(0, 10), 2);
86 assert_eq!(crg.next_range(0, 10), 4);
87 }
88
89 #[test]
90 fn random_from_vec_should_be_same() {
91 let vec = vec![432, 6542, 534, 6, 13, 645, 88, 2352, 345, 2667, 8287];
92 let mut crg = CustomNumberGenerator::default();
93 assert_eq!(*crg.get_random_from_vec(&vec), 6);
94 assert_eq!(*crg.get_random_from_vec(&vec), 2667);
95 assert_eq!(*crg.get_random_from_vec(&vec), 534);
96 assert_eq!(*crg.get_random_from_vec(&vec), 8287);
97 assert_eq!(*crg.get_random_from_vec(&vec), 6);
98 }
99}