/// splitmix64: seeded, so a failing case replays from its seed.
pub(crate) struct Rng(pub(crate) u64);
impl Rng {
pub(crate) fn next(&mut self) -> u64 {
self.0 = self.0.wrapping_add(0x9e37_79b9_7f4a_7c15);
let mut z = self.0;
z = (z ^ (z >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
z = (z ^ (z >> 27)).wrapping_mul(0x94d0_49bb_1331_11eb);
z ^ (z >> 31)
}
pub(crate) fn below(&mut self, n: usize) -> usize {
(self.next() % n.max(1) as u64) as usize
}
pub(crate) fn range(&mut self, low: usize, high: usize) -> usize {
low + self.below(high - low + 1)
}
pub(crate) fn odds(&mut self, percent: usize) -> bool {
self.below(100) < percent
}
pub(crate) fn pick<'a, T>(&mut self, items: &'a [T]) -> &'a T {
&items[self.below(items.len())]
}
}