#[derive(Debug, Clone)]
pub struct Rng {
state: u64,
}
impl Rng {
pub fn new(seed: u64) -> Self {
Self {
state: if seed == 0 { 0xdeadbeef } else { seed },
}
}
pub fn next_u64(&mut self) -> u64 {
let mut x = self.state;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
self.state = x;
x
}
pub fn next_usize(&mut self, max: usize) -> usize {
if max == 0 {
return 0;
}
(self.next_u64() as usize) % max
}
pub fn next_i64(&mut self) -> i64 {
self.next_u64() as i64
}
pub fn next_bool(&mut self) -> bool {
self.next_u64() % 2 == 0
}
pub fn next_f64(&mut self) -> f64 {
(self.next_u64() as f64) / (u64::MAX as f64)
}
pub fn next_bytes(&mut self, len: usize) -> Vec<u8> {
(0..len).map(|_| self.next_u64() as u8).collect()
}
pub fn next_string(&mut self, len: usize) -> String {
let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()'\"\\;-- \n\r\t\x00";
(0..len)
.map(|_| chars.as_bytes()[self.next_usize(chars.len())] as char)
.collect()
}
}