2020-08-21 05:27:26 +00:00
|
|
|
use std::cell::Cell;
|
2021-05-02 12:26:13 +00:00
|
|
|
use std::ops::{Range};
|
2020-12-25 22:39:41 +00:00
|
|
|
|
|
|
|
pub trait RNG {
|
|
|
|
fn next(&self) -> i32;
|
|
|
|
|
|
|
|
fn range(&self, range: Range<i32>) -> i32 {
|
2021-02-12 22:48:42 +00:00
|
|
|
range.start + ((self.next() & 0x7fffffff) % (range.len() as i32 + 1))
|
2020-12-25 22:39:41 +00:00
|
|
|
}
|
|
|
|
}
|
2020-08-21 05:27:26 +00:00
|
|
|
|
2020-11-28 19:25:51 +00:00
|
|
|
/// Deterministic XorShift-based random number generator
|
2021-05-02 12:26:13 +00:00
|
|
|
pub struct XorShift(Cell<u64>);
|
2020-09-05 01:03:43 +00:00
|
|
|
|
2020-12-25 22:39:41 +00:00
|
|
|
impl XorShift {
|
2020-08-21 05:27:26 +00:00
|
|
|
pub fn new(seed: i32) -> Self {
|
2021-05-02 12:26:13 +00:00
|
|
|
Self(Cell::new(seed as u64))
|
2020-09-05 01:03:43 +00:00
|
|
|
}
|
|
|
|
|
2021-05-02 12:26:13 +00:00
|
|
|
pub fn next_u64(&self) -> u64 {
|
2020-09-05 01:03:43 +00:00
|
|
|
let mut state = self.0.get();
|
|
|
|
|
2021-05-02 12:26:13 +00:00
|
|
|
state ^= state >> 12;
|
|
|
|
state ^= state << 25;
|
|
|
|
state ^= state >> 27;
|
2020-09-05 01:03:43 +00:00
|
|
|
|
|
|
|
self.0.replace(state);
|
2021-05-02 12:26:13 +00:00
|
|
|
|
|
|
|
state.wrapping_mul(0x2545F4914F6CDD1Du64)
|
2020-08-20 18:31:47 +00:00
|
|
|
}
|
|
|
|
|
2020-09-05 04:26:01 +00:00
|
|
|
#[inline]
|
2020-08-21 05:27:26 +00:00
|
|
|
pub fn next_u32(&self) -> u32 {
|
2021-05-02 12:26:13 +00:00
|
|
|
(self.next_u64() >> 32) as u32
|
2020-08-20 18:31:47 +00:00
|
|
|
}
|
|
|
|
|
2021-05-02 12:26:13 +00:00
|
|
|
pub fn dump_state(&self) -> u64 {
|
2020-11-28 19:25:51 +00:00
|
|
|
self.0.get()
|
|
|
|
}
|
|
|
|
|
2021-05-02 12:26:13 +00:00
|
|
|
pub fn load_state(&mut self, saved_state: u64) {
|
2020-11-28 19:25:51 +00:00
|
|
|
self.0.replace(saved_state);
|
|
|
|
}
|
2020-12-25 22:39:41 +00:00
|
|
|
}
|
2020-11-28 19:25:51 +00:00
|
|
|
|
2020-12-25 22:39:41 +00:00
|
|
|
impl RNG for XorShift {
|
|
|
|
#[inline]
|
|
|
|
fn next(&self) -> i32 {
|
2021-05-02 12:26:13 +00:00
|
|
|
self.next_u32() as i32
|
2020-08-20 18:31:47 +00:00
|
|
|
}
|
|
|
|
}
|
2020-12-06 20:20:26 +00:00
|
|
|
|
2020-12-25 22:39:41 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Xoroshiro32PlusPlus(Cell<(u16, u16)>);
|
2020-12-06 20:20:26 +00:00
|
|
|
|
|
|
|
impl Xoroshiro32PlusPlus {
|
|
|
|
pub fn new(seed: u32) -> Xoroshiro32PlusPlus {
|
2020-12-25 22:39:41 +00:00
|
|
|
Xoroshiro32PlusPlus(Cell::new((
|
2020-12-06 20:20:26 +00:00
|
|
|
(seed & 0xffff) as u16,
|
|
|
|
(seed >> 16 & 0xffff) as u16
|
2020-12-25 22:39:41 +00:00
|
|
|
)))
|
2020-12-06 20:20:26 +00:00
|
|
|
}
|
|
|
|
|
2020-12-25 22:39:41 +00:00
|
|
|
pub fn next_u16(&self) -> u16 {
|
|
|
|
let mut state = self.0.get();
|
2021-02-10 11:53:49 +00:00
|
|
|
let result = (state.0.wrapping_add(state.1)).rotate_left(9).wrapping_add(state.0);
|
2020-12-25 22:39:41 +00:00
|
|
|
|
|
|
|
state.1 ^= state.0;
|
|
|
|
state.0 = state.0.rotate_left(13) ^ state.1 ^ (state.1 << 5);
|
|
|
|
state.1 = state.1.rotate_left(10);
|
2020-12-06 20:20:26 +00:00
|
|
|
|
2020-12-25 22:39:41 +00:00
|
|
|
self.0.replace(state);
|
2020-12-06 20:20:26 +00:00
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dump_state(&self) -> u32 {
|
2020-12-25 22:39:41 +00:00
|
|
|
let state = self.0.get();
|
|
|
|
|
|
|
|
(state.0 as u32) | (state.1 as u32) << 16
|
2020-12-06 20:20:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn load_state(&mut self, state: u32) {
|
2020-12-25 22:39:41 +00:00
|
|
|
self.0.replace((
|
|
|
|
(state & 0xffff) as u16,
|
|
|
|
((state >> 16) & 0xffff) as u16
|
|
|
|
));
|
2020-12-06 20:20:26 +00:00
|
|
|
}
|
2020-12-25 22:39:41 +00:00
|
|
|
}
|
2020-12-06 20:20:26 +00:00
|
|
|
|
2020-12-25 22:39:41 +00:00
|
|
|
impl RNG for Xoroshiro32PlusPlus {
|
|
|
|
fn next(&self) -> i32 {
|
2021-01-16 13:51:12 +00:00
|
|
|
((self.next_u16() as u32) << 16 | self.next_u16() as u32) as i32
|
2020-12-06 20:20:26 +00:00
|
|
|
}
|
|
|
|
}
|