rand.rs (1698B)
1 pub trait RandOutput: 2 Copy + Ord + std::ops::Sub<Output = Self> + std::fmt::Debug + Default 3 { 4 } 5 impl<T: Copy + Ord + std::ops::Sub<Output = Self> + std::fmt::Debug + Default> RandOutput for T {} 6 7 pub trait Rand: Copy { 8 type Output: RandOutput; 9 const MAX: Self::Output; 10 11 fn rand(&mut self) -> Self::Output; 12 } 13 14 pub trait YesNo<T: RandOutput>: Rand<Output = T> { 15 fn yesno(&mut self, limit: T) -> (bool, bool) { 16 let r = self.rand(); 17 (r < limit, Self::MAX - r < limit) 18 } 19 } 20 21 impl<T, R> YesNo<T> for R 22 where 23 T: RandOutput, 24 R: Rand<Output = T>, 25 { 26 } 27 28 #[derive(Clone, Copy)] 29 pub struct Lehmer { 30 state: std::num::Wrapping<u128>, 31 } 32 33 impl Default for Lehmer { 34 fn default() -> Self { 35 let now = std::time::SystemTime::now() 36 .duration_since(std::time::SystemTime::UNIX_EPOCH) 37 .expect("Failed to initialize random"); 38 Self::new(u128::from(now.subsec_nanos()) << 64 | u128::from(now.as_secs()) | 1) 39 } 40 } 41 42 impl Lehmer { 43 pub fn new(seed: u128) -> Self { 44 Self { 45 state: std::num::Wrapping(seed), 46 } 47 } 48 49 pub fn new_with<T: Into<u128>>(other: &mut impl Rand<Output = T>) -> Self { 50 Self::new( 51 other.rand().into() << 96 52 ^ other.rand().into() << 64 53 ^ other.rand().into() << 32 54 ^ other.rand().into() 55 | 1, 56 ) 57 } 58 } 59 60 impl Rand for Lehmer { 61 type Output = u32; 62 const MAX: Self::Output = Self::Output::MAX; 63 64 #[allow(clippy::cast_possible_truncation)] 65 fn rand(&mut self) -> Self::Output { 66 self.state *= 0xda94_2042_e4dd_58b5; 67 (self.state >> 64).0 as Self::Output 68 } 69 }