#![allow(clippy::unreadable_literal, clippy::upper_case_acronyms)]
const N: usize = 624;
const M: usize = 397;
const MATRIX_A: u32 = 0x9908b0dfu32;
const UPPER_MASK: u32 = 0x80000000u32;
const LOWER_MASK: u32 = 0x7fffffffu32;
pub struct MT19937 {
mt: [u32; N],
mti: usize,
}
const MT19937_DEFAULT: MT19937 = MT19937 {
mt: [0; N],
mti: N + 1,
};
impl Default for MT19937 {
#[inline]
fn default() -> Self {
MT19937_DEFAULT
}
}
impl std::fmt::Debug for MT19937 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.pad("MT19937")
}
}
impl MT19937 {
#[inline]
pub fn new_with_slice_seed(init_key: &[u32]) -> Self {
let mut state = Self::default();
state.seed_slice(init_key);
state
}
fn seed(&mut self, s: u32) {
self.mt[0] = s;
self.mti = 1;
while self.mti < N {
self.mt[self.mti] = 1812433253u32
.wrapping_mul(self.mt[self.mti - 1] ^ (self.mt[self.mti - 1] >> 30))
+ self.mti as u32;
self.mti += 1;
}
}
pub fn seed_slice(&mut self, init_key: &[u32]) {
let mut i;
let mut j;
let mut k;
self.seed(19650218);
i = 1;
j = 0;
k = if N > init_key.len() {
N
} else {
init_key.len()
};
while k != 0 {
self.mt[i] = (self.mt[i]
^ ((self.mt[i - 1] ^ (self.mt[i - 1] >> 30)).wrapping_mul(1664525u32)))
.wrapping_add(init_key[j])
.wrapping_add(j as u32);
self.mt[i] &= 0xffffffffu32;
i += 1;
j += 1;
if i >= N {
self.mt[0] = self.mt[N - 1];
i = 1;
}
if j >= init_key.len() {
j = 0;
}
k -= 1;
}
k = N - 1;
while k != 0 {
self.mt[i] = (self.mt[i]
^ ((self.mt[i - 1] ^ (self.mt[i - 1] >> 30)).wrapping_mul(1566083941u32)))
.wrapping_sub(i as u32);
self.mt[i] &= 0xffffffffu32;
i += 1;
if i >= N {
self.mt[0] = self.mt[N - 1];
i = 1;
}
k -= 1;
}
self.mt[0] = 0x80000000u32;
}
fn gen_u32(&mut self) -> u32 {
let mut y: u32;
let mag01 = |x| if (x & 0x1) == 1 { MATRIX_A } else { 0 };
if self.mti >= N {
if self.mti == N + 1
{
self.seed(5489u32);
}
for kk in 0..N - M {
y = (self.mt[kk] & UPPER_MASK) | (self.mt[kk + 1] & LOWER_MASK);
self.mt[kk] = self.mt[kk + M] ^ (y >> 1) ^ mag01(y);
}
for kk in N - M..N - 1 {
y = (self.mt[kk] & UPPER_MASK) | (self.mt[kk + 1] & LOWER_MASK);
self.mt[kk] = self.mt[kk.wrapping_add(M.wrapping_sub(N))] ^ (y >> 1) ^ mag01(y);
}
y = (self.mt[N - 1] & UPPER_MASK) | (self.mt[0] & LOWER_MASK);
self.mt[N - 1] = self.mt[M - 1] ^ (y >> 1) ^ mag01(y);
self.mti = 0;
}
y = self.mt[self.mti];
self.mti += 1;
y ^= y >> 11;
y ^= (y << 7) & 0x9d2c5680u32;
y ^= (y << 15) & 0xefc60000u32;
y ^= y >> 18;
y
}
}
pub fn gen_res53<R: rand_core::RngCore>(rng: &mut R) -> f64 {
let a = rng.next_u32() >> 5;
let b = rng.next_u32() >> 6;
(a as f64 * 67108864.0 + b as f64) * (1.0 / 9007199254740992.0)
}
impl rand_core::RngCore for MT19937 {
#[inline]
fn next_u32(&mut self) -> u32 {
self.gen_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
rand_core::impls::next_u64_via_u32(self)
}
#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
rand_core::impls::fill_bytes_via_next(self, dest)
}
#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
self.fill_bytes(dest);
Ok(())
}
}
pub struct Seed(pub [u32; N]);
impl Default for Seed {
#[inline]
fn default() -> Self {
Seed([0; N])
}
}
impl AsMut<[u8]> for Seed {
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
unsafe { self.0.align_to_mut().1 }
}
}
impl rand_core::SeedableRng for MT19937 {
type Seed = Seed;
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
Self::new_with_slice_seed(&seed.0[..])
}
}