pub trait Rng {
fn next_u64(&mut self) -> u64;
fn next_u32(&mut self) -> u32 {
self.next_u64() as u32
}
fn next_u8(&mut self) -> u8 {
self.next_u64() as u8
}
fn chance(&mut self, numerator: u32, denominator: u32) -> bool {
if denominator == 0 {
return false;
}
(self.next_u32() % denominator) < numerator
}
fn index(&mut self, len: usize) -> usize {
if len == 0 {
return 0;
}
(self.next_u64() as usize) % len
}
}
#[derive(Debug, Clone)]
pub struct Xorshift64 {
state: u64,
}
impl Xorshift64 {
pub fn new(seed: u64) -> Self {
Self {
state: if seed == 0 {
0xDECA_FC0F_FEEC_AFE1
} else {
seed
},
}
}
}
impl Rng for Xorshift64 {
fn next_u64(&mut self) -> u64 {
let mut x = self.state;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
self.state = x;
x
}
}