Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up
Find file
Copy path
Fetching contributors…
| pub mod random { | |
| pub trait Rand { | |
| fn rand_u32(&mut self) -> u32; | |
| fn rand_u8(&mut self) -> u8 { | |
| return self.rand_u32() as u8; | |
| } | |
| fn rand_u16(&mut self) -> u16 { | |
| return self.rand_u32() as u16; | |
| } | |
| fn rand_u64(&mut self) -> u64 { | |
| return (self.rand_u32() as u64)<<32 | (self.rand_u32() as u64); | |
| } | |
| #[cfg(target_pointer_width = "32")] | |
| fn rand_usize(&mut self) -> usize { | |
| return self.rand_u32() as usize; | |
| } | |
| #[cfg(target_pointer_width = "64")] | |
| fn rand_usize(&mut self) -> usize { | |
| return self.rand_u64() as usize; | |
| } | |
| fn rand_bounded_u32(&mut self, m: u32) -> u32 { | |
| let threshold = m.wrapping_neg().wrapping_rem(m); | |
| loop { | |
| let r = self.rand_u32(); | |
| if r >= threshold { | |
| return r.wrapping_rem(m); | |
| } | |
| } | |
| } | |
| fn rand_bounded_u64(&mut self, m: u64) -> u64 { | |
| let threshold = m.wrapping_neg().wrapping_rem(m); | |
| loop { | |
| let r = self.rand_u64(); | |
| if r >= threshold { | |
| return r.wrapping_rem(m); | |
| } | |
| } | |
| } | |
| #[cfg(target_pointer_width = "32")] | |
| fn rand_bounded_usize(&mut self, m: usize) -> usize{ | |
| return self.rand_bounded_u32(m as u32) as usize; | |
| } | |
| #[cfg(target_pointer_width = "64")] | |
| fn rand_bounded_usize(&mut self, m: usize) -> usize{ | |
| return self.rand_bounded_u64(m as u64) as usize; | |
| } | |
| fn rand_range_u32(&mut self, a: u32, b: u32) -> u32 { | |
| return a+self.rand_bounded_u32(b-a); | |
| } | |
| fn rand_range_u64(&mut self, a: u64, b: u64) -> u64 { | |
| return a+self.rand_bounded_u64(b-a); | |
| } | |
| fn rand_range_i32(&mut self, a: i32, b: i32) -> i32 { | |
| return a+self.rand_bounded_u32((b-a) as u32) as i32; | |
| } | |
| fn rand_range_i64(&mut self, a: i64, b: i64) -> i64 { | |
| return a+self.rand_bounded_u64((b-a) as u64) as i64; | |
| } | |
| fn shuffle<T>(&mut self, a: &mut [T]) { | |
| if a.len()==0 {return;} | |
| let mut i = a.len()-1; | |
| while i>0 { | |
| let j = (self.rand_u32() as usize)%(i+1); | |
| a.swap(i,j); | |
| i-=1; | |
| } | |
| } | |
| fn rand_f32(&mut self) -> f32 { | |
| return self.rand_u32() as f32 * 2.3283064365386963E-10; | |
| } | |
| fn rand_f64(&mut self) -> f64 { | |
| return self.rand_u32() as f64 * 2.3283064365386963E-10; | |
| } | |
| } | |
| // PCG-XSH-RR | |
| const MULTIPLIER: u64 = 6364136223846793005; | |
| const INC: u64 = 1442695040888963407; | |
| pub struct Rng { | |
| state: u64 | |
| } | |
| impl Rng { | |
| fn rand(&mut self) -> u32 { | |
| let oldstate = self.state; | |
| self.state = oldstate.wrapping_mul(MULTIPLIER).wrapping_add(INC|1); | |
| let xorshifted: u32 = (( | |
| (oldstate.wrapping_shr(18)) ^ oldstate | |
| ).wrapping_shr(27)) as u32; | |
| let rot: u32 = (oldstate.wrapping_shr(59)) as u32; | |
| return (xorshifted.wrapping_shr(rot)) | ( | |
| xorshifted.wrapping_shl(rot.wrapping_neg() & 31) | |
| ); | |
| } | |
| pub fn new(seed: u64) -> Self { | |
| let mut rng = Self{state: 0}; | |
| rng.rand(); | |
| rng.state = rng.state.wrapping_add(seed); | |
| rng.rand(); | |
| return rng; | |
| } | |
| } | |
| impl Rand for Rng { | |
| fn rand_u32(&mut self) -> u32 { | |
| return self.rand(); | |
| } | |
| } | |
| // LCG from "Numerical Recipes" | |
| const A: u32 = 1664525; | |
| const C: u32 = 1013904223; | |
| pub struct LcRng { | |
| state: u32 | |
| } | |
| impl LcRng { | |
| fn rand(&mut self) -> u32 { | |
| let y = self.state.wrapping_mul(A).wrapping_add(C); | |
| self.state = y; | |
| return y; | |
| } | |
| pub fn new(seed: u64) -> Self { | |
| return Self{state: seed as u32}; | |
| } | |
| } | |
| impl Rand for LcRng { | |
| fn rand_u32(&mut self) -> u32 { | |
| return self.rand(); | |
| } | |
| fn rand_bounded_u32(&mut self, m: u32) -> u32 { | |
| let p = (self.rand_u32() as u64).wrapping_mul(m as u64); | |
| return p.wrapping_shr(32) as u32; | |
| } | |
| fn rand_bounded_u64(&mut self, m: u64) -> u64 { | |
| return self.rand_u64().wrapping_rem(m); | |
| } | |
| } | |
| } | |
| use random::{Rng,Rand}; | |
| fn main() { | |
| let mut rng = Rng::new(0); | |
| let mut v: Vec<u32> = (0..100).collect(); | |
| rng.shuffle(&mut v); | |
| println!("{:?}\n",v); | |
| v = (0..100).map(|_| rng.rand_range_u32(1,7)).collect(); | |
| println!("{:?}",v); | |
| } | |