#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SplitMix64 {
state: u64,
}
impl SplitMix64 {
pub const fn new(seed: u64) -> SplitMix64 {
SplitMix64 { state: seed }
}
pub fn next_u64(&mut self) -> u64 {
self.state = self.state.wrapping_add(0x9E37_79B9_7F4A_7C15);
let mut z = self.state;
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
z ^ (z >> 31)
}
}
const PCG_MUL: u64 = 6_364_136_223_846_793_005;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Pcg32 {
state: u64,
inc: u64,
}
impl Pcg32 {
pub fn new(seed: u64, stream: u64) -> Pcg32 {
let mut g = Pcg32 { state: 0, inc: (stream << 1) | 1 };
g.step();
g.state = g.state.wrapping_add(seed);
g.step();
g
}
pub fn derive(seed: u64, id: u64) -> Pcg32 {
let mut m = SplitMix64::new(seed ^ id.wrapping_mul(0xD6E8_FEB8_6659_FD93));
let s = m.next_u64();
let st = m.next_u64();
Pcg32::new(s, st)
}
fn step(&mut self) {
self.state = self.state.wrapping_mul(PCG_MUL).wrapping_add(self.inc);
}
pub fn next_u32(&mut self) -> u32 {
let old = self.state;
self.step();
let xs = (((old >> 18) ^ old) >> 27) as u32;
let rot = (old >> 59) as u32;
xs.rotate_right(rot)
}
pub fn next_u64(&mut self) -> u64 {
let hi = self.next_u32() as u64;
(hi << 32) | self.next_u32() as u64
}
pub fn below(&mut self, n: u32) -> u32 {
if n == 0 {
return 0;
}
let threshold = n.wrapping_neg() % n;
loop {
let r = self.next_u32();
if r >= threshold {
return r % n;
}
}
}
fn below64(&mut self, n: u64) -> u64 {
if n == 0 {
return 0;
}
let threshold = n.wrapping_neg() % n;
loop {
let r = self.next_u64();
if r >= threshold {
return r % n;
}
}
}
pub fn range(&mut self, lo: i64, hi: i64) -> i64 {
if hi <= lo {
return lo;
}
let span = hi as i128 - lo as i128 + 1; if span <= u32::MAX as i128 {
return lo + self.below(span as u32) as i64;
}
if span == 1i128 << 64 {
return self.next_u64() as i64;
}
let span = span as u64;
let threshold = span.wrapping_neg() % span;
loop {
let r = self.next_u64();
if r >= threshold {
return (lo as i128 + (r % span) as i128) as i64;
}
}
}
pub fn f64(&mut self) -> f64 {
(self.next_u64() >> 11) as f64 * (1.0 / 9_007_199_254_740_992.0)
}
pub fn chance(&mut self, num: u32, den: u32) -> bool {
num >= den || (den > 0 && self.below(den) < num)
}
pub fn chance_ppm(&mut self, ppm: u32) -> bool {
self.chance(ppm, 1_000_000)
}
pub fn fill(&mut self, out: &mut [u8]) {
for c in out.chunks_mut(4) {
let r = self.next_u32().to_le_bytes();
c.copy_from_slice(&r[..c.len()]);
}
}
pub fn shuffle<T>(&mut self, v: &mut [T]) {
let mut i = v.len();
while i > 1 {
let j = if i <= u32::MAX as usize { self.below(i as u32) as usize } else { self.below64(i as u64) as usize };
i -= 1;
v.swap(i, j);
}
}
pub fn advance(&mut self, mut delta: u64) {
let (mut acc_mul, mut acc_add) = (1u64, 0u64);
let (mut cur_mul, mut cur_add) = (PCG_MUL, self.inc);
while delta > 0 {
if delta & 1 != 0 {
acc_mul = acc_mul.wrapping_mul(cur_mul);
acc_add = acc_add.wrapping_mul(cur_mul).wrapping_add(cur_add);
}
cur_add = cur_mul.wrapping_add(1).wrapping_mul(cur_add);
cur_mul = cur_mul.wrapping_mul(cur_mul);
delta >>= 1;
}
self.state = acc_mul.wrapping_mul(self.state).wrapping_add(acc_add);
}
}