// codesnip-guard: random_generator #[cfg_attr(any(),rustfmt::skip)]pub use self::random_generator::{NotEmptySegment,RandIter,RandRange,RandomSpec,Spec,WeightedSampler,WithEmptySegment,from_fn,spec};#[cfg_attr(any(),rustfmt::skip)]mod random_generator{use super::Xorshift;use std::{marker::PhantomData,mem::swap,ops::{Bound,Range,RangeFrom,RangeFull,RangeInclusive,RangeTo,RangeToInclusive}};#[doc=" Trait for spec of generating random value."]pub trait RandomSpec:Sized{#[doc=" Return a random value."]fn rand(&self,rng:&mut Xorshift)->T;#[doc=" Return an iterator that generates random values."]fn rand_iter(self,rng:&mut Xorshift)->RandIter<'_,T,Self>{RandIter{spec:self,rng,_marker:PhantomData}}}pub struct Spec{generate:F,_marker:PhantomDataT>}#[doc=" Wraps a random specification for composition."]pub fn spec(source:R)->SpecT>where R:RandomSpec{from_fn(move|rng|source.rand(rng))}#[doc=" Calls `generate` with the RNG whenever a value is requested."]pub fn from_fn(generate:F)->Specwhere F:Fn(&mut Xorshift)->T{Spec{generate,_marker:PhantomData}}implSpecwhere F:Fn(&mut Xorshift)->T{#[doc=" Samples the length once, then generates that many elements."]pub fn vec(self,length:R)->Spec,impl Fn(&mut Xorshift)->Vec>where R:RandomSpec{from_fn(move|rng|{let n=rng.random(&length);rng.random_iter(&self).take(n).collect()})}}implRandomSpecfor Specwhere F:Fn(&mut Xorshift)->T{fn rand(&self,rng:&mut Xorshift)->T{(self.generate)(rng)}}impl Xorshift{pub fn random(&mut self,spec:R)->T where R:RandomSpec{spec.rand(self)}pub fn random_iter(&mut self,spec:R)->RandIter<'_,T,R>where R:RandomSpec{spec.rand_iter(self)}}#[derive(Debug)]pub struct RandIter<'r,T,R>where R:RandomSpec{spec:R,rng:&'r mut Xorshift,_marker:PhantomDataT>}implIterator for RandIter<'_,T,R>where R:RandomSpec{type Item=T;fn next(&mut self)->Option{Some(self.spec.rand(self.rng))}fn size_hint(&self)->(usize,Option){(usize::MAX,None)}}macro_rules!impl_random_spec_range_full{($($t:ty)*)=>{$(impl RandomSpec<$t>for RangeFull{fn rand(&self,rng:&mut Xorshift)->$t{rng.rand64()as _}})*};}impl_random_spec_range_full!(u8 u16 u32 u64 usize i8 i16 i32 i64 isize);impl RandomSpecfor RangeFull{fn rand(&self,rng:&mut Xorshift)->u128{((rng.rand64()as u128)<<64)|rng.rand64()as u128}}impl RandomSpecfor RangeFull{fn rand(&self,rng:&mut Xorshift)->i128{rng.random::(..)as i128}}macro_rules!impl_random_spec_ranges{($($u:ident$i:ident)*)=>{$(impl RandomSpec<$u>for Range<$u>{fn rand(&self,rng:&mut Xorshift)->$u{assert!(self.start(..)%len)}}impl RandomSpec<$i>for Range<$i>{fn rand(&self,rng:&mut Xorshift)->$i{assert!(self.start(..)%len)}}impl RandomSpec<$u>for RangeFrom<$u>{fn rand(&self,rng:&mut Xorshift)->$u{let len=($u::MAX-self.start).wrapping_add(1);let x=rng.random::<$u,_>(..);self.start+if len!=0{x%len}else{x}}}impl RandomSpec<$i>for RangeFrom<$i>{fn rand(&self,rng:&mut Xorshift)->$i{let len=($i::MAX.abs_diff(self.start)).wrapping_add(1);let x=rng.random::<$u,_>(..);self.start.wrapping_add_unsigned(if len!=0{x%len}else{x})}}impl RandomSpec<$u>for RangeInclusive<$u>{fn rand(&self,rng:&mut Xorshift)->$u{assert!(self.start()<=self.end());let len=(self.end()-self.start()).wrapping_add(1);let x=rng.random::<$u,_>(..);self.start()+if len!=0{x%len}else{x}}}impl RandomSpec<$i>for RangeInclusive<$i>{fn rand(&self,rng:&mut Xorshift)->$i{assert!(self.start()<=self.end());let len=(self.end().abs_diff(*self.start())).wrapping_add(1);let x=rng.random::<$u,_>(..);self.start().wrapping_add_unsigned(if len!=0{x%len}else{x})}}impl RandomSpec<$u>for RangeTo<$u>{fn rand(&self,rng:&mut Xorshift)->$u{let len=self.end;rng.random::<$u,_>(..)%len}}impl RandomSpec<$i>for RangeTo<$i>{fn rand(&self,rng:&mut Xorshift)->$i{let len=self.end.abs_diff($i::MIN);$i::MIN.wrapping_add_unsigned(rng.random::<$u,_>(..)%len)}}impl RandomSpec<$u>for RangeToInclusive<$u>{fn rand(&self,rng:&mut Xorshift)->$u{let len=(self.end).wrapping_add(1);let x=rng.random::<$u,_>(..);if len!=0{x%len}else{x}}}impl RandomSpec<$i>for RangeToInclusive<$i>{fn rand(&self,rng:&mut Xorshift)->$i{let len=(self.end.abs_diff($i::MIN)).wrapping_add(1);let x=rng.random::<$u,_>(..);$i::MIN.wrapping_add_unsigned(if len!=0{x%len}else{x})}})*};}impl_random_spec_ranges!(u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 usize isize);macro_rules!impl_random_spec_tuple{($($T:ident)*,$($R:ident)*,$($v:ident)*)=>{impl<$($T),*,$($R),*>RandomSpec<($($T,)*)>for($($R,)*)where$($R:RandomSpec<$T>),*{fn rand(&self,rng:&mut Xorshift)->($($T,)*){let($($v,)*)=self;($(($v).rand(rng),)*)}}};}impl_random_spec_tuple!(A,RA,a);impl_random_spec_tuple!(A B,RA RB,a b);impl_random_spec_tuple!(A B C,RA RB RC,a b c);impl_random_spec_tuple!(A B C D,RA RB RC RD,a b c d);impl_random_spec_tuple!(A B C D E,RA RB RC RD RE,a b c d e);impl_random_spec_tuple!(A B C D E F,RA RB RC RD RE RF,a b c d e f);impl_random_spec_tuple!(A B C D E F G,RA RB RC RD RE RF RG,a b c d e f g);impl_random_spec_tuple!(A B C D E F G H,RA RB RC RD RE RF RG RH,a b c d e f g h);impl_random_spec_tuple!(A B C D E F G H I,RA RB RC RD RE RF RG RH RI,a b c d e f g h i);impl_random_spec_tuple!(A B C D E F G H I J,RA RB RC RD RE RF RG RH RI RJ,a b c d e f g h i j);macro_rules!impl_random_spec_primitive{($($t:ty)*)=>{$(impl RandomSpec<$t>for$t{fn rand(&self,_rng:&mut Xorshift)->$t{*self}})*};}impl_random_spec_primitive!(()u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize bool char);implRandomSpecfor&R where R:RandomSpec{fn rand(&self,rng:&mut Xorshift)->T{>::rand(self,rng)}}implRandomSpecfor&mut R where R:RandomSpec{fn rand(&self,rng:&mut Xorshift)->T{>::rand(self,rng)}}#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Hash)]#[doc=" Left-close Right-open No Empty Segment"]pub struct NotEmptySegment(pub T);implRandomSpec<(usize,usize)>for NotEmptySegmentwhere T:RandomSpec{fn rand(&self,rng:&mut Xorshift)->(usize,usize){let n=rng.random(&self.0)as u64;let k=randint_uniform(rng,n);let l=randint_uniform(rng,n-k)as usize;(l,l+k as usize+1)}}#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Hash)]#[doc=" Left-close Right-open Segment"]pub struct WithEmptySegment(pub T);implRandomSpec<(usize,usize)>for WithEmptySegmentwhere T:RandomSpec{fn rand(&self,rng:&mut Xorshift)->(usize,usize){let n=rng.random(&self.0)as u64;let k=randint_uniform(rng,n+1);let l=randint_uniform(rng,n-k+1)as usize;(l,l+k as usize)}}#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Hash)]pub struct RandRange{data:Q,_marker:PhantomDataT>}implRandRange{pub fn new(data:Q)->Self{Self{data,_marker:PhantomData}}}implRandomSpec<(Bound,Bound)>for RandRangewhere Q:RandomSpec,T:Ord{fn rand(&self,rng:&mut Xorshift)->(Bound,Bound){let mut l=rng.random(&self.data);let mut r=rng.random(&self.data);if l>r{swap(&mut l,&mut r);}(match rng.rand(3){0=>Bound::Excluded(l),1=>Bound::Included(l),_=>Bound::Unbounded,},match rng.rand(3){0=>Bound::Excluded(r),1=>Bound::Included(r),_=>Bound::Unbounded,})}}#[inline]fn randint_uniform(rng:&mut Xorshift,k:u64)->u64{let mut v=rng.rand64();if k>0{v%=k;}v}pub struct WeightedSampler{n:usize,prob:Vec,alias:Vec}impl WeightedSampler{pub fn new(weights:impl IntoIterator)->Self{let mut weights:Vec<_>=weights.into_iter().collect();let n=weights.len();assert!(n>0,"weights must be non-empty");let mut prob=vec![0.0;n];let mut alias=vec![0;n];let mut small=vec![];let mut large=vec![];let sum:f64=weights.iter().sum();assert!(sum>0.0,"sum of weights must be positive");let mut scale=n as f64/sum;if!sum.is_finite()||!scale.is_finite(){let max=weights.iter().fold(0.0f64,|max,&weight|{assert!(weight.is_finite()&&weight>=0.0,"weights must be finite and non-negative");max.max(weight)});let sum:f64=weights.iter_mut().map(|weight|{*weight/=max;*weight}).sum();scale=n as f64/sum;}for(i,weight)in weights.iter_mut().enumerate(){assert!(*weight>=0.0,"weights must be non-negative");*weight*=scale;if*weight<1.0{small.push(i);}else{large.push(i);}}while let Some(&g)=large.last(){let Some(l)=small.pop()else{break;};prob[l]=weights[l];alias[l]=g;weights[g]-=1.0-weights[l];if weights[g]<1.0{large.pop();small.push(g);}}for g in small.into_iter().chain(large).rev(){prob[g]=1.0;alias[g]=g;}Self{n,prob,alias}}}impl RandomSpecfor WeightedSampler{fn rand(&self,rng:&mut Xorshift)->usize{let i=rng.rand(self.n as u64)as usize;if rng.randf(){::std::iter::repeat_with(||$crate::rand_value!(@inner$rng,[]$($t)*))$(.take($len).collect::<::std::vec::Vec<_>>())?};(@array$rng:expr,[$($t:tt)*]$len:expr)=>{{let values:[_;$len]=::std::array::from_fn(|_|$crate::rand_value!(@inner$rng,[]$($t)*));values}};(@group$rng:expr,[])=>{()};(@group$rng:expr,[$($args:tt)*],$($t:tt)*)=>{$crate::rand_value!(@tuple$rng,[$($args)*]$($t)*)};(@tuple$rng:expr,[$([$($args:tt)*])*])=>{($($($args)*,)*)};(@$tag:ident$rng:expr,[[$($args:tt)*]])=>{$($args)*};(@$tag:ident$rng:expr,[$($args:tt)*]($($tuple:tt)*)$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@group$rng,[]$($tuple)*)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][[$($tt:tt)*];const$len:expr]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@array$rng,[[$($tt)*]]$len)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][[$($tt:tt)*];$len:expr]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@repeat$rng,[[$($tt)*]]$len)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][($($tt:tt)*);const$len:expr]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@array$rng,[($($tt)*)]$len)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][($($tt:tt)*);$len:expr]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@repeat$rng,[($($tt)*)]$len)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][$ty:expr;const$len:expr]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@array$rng,[$ty]$len)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][$ty:expr;$len:expr]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@repeat$rng,[$ty]$len)]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*][$($tt:tt)*]$(,$($t:tt)*)?)=>{$crate::rand_value!(@$tag$rng,[$($args)*[$crate::rand_value!(@repeat$rng,[$($tt)*])]]$(,$($t)*)?)};(@$tag:ident$rng:expr,[$($args:tt)*]$ty:expr)=>{$crate::rand_value!(@$tag$rng,[$($args)*[($rng).random($ty)]])};(@$tag:ident$rng:expr,[$($args:tt)*]$ty:expr,$($t:tt)*)=>{$crate::rand_value!(@$tag$rng,[$($args)*[($rng).random($ty)]],$($t)*)};(@$tag:ident$rng:expr,[$($args:tt)*],$($t:tt)*)=>{$crate::rand_value!(@$tag$rng,[$($args)*]$($t)*)};(@$tag:ident$rng:expr,[$($args:tt)*])=>{::std::compile_error!(::std::stringify!($($args)*))};($rng:expr,$($t:tt)*)=>{$crate::rand_value!(@inner$rng,[]$($t)*)}}#[macro_export]#[doc=" Declare random values using [`RandomSpec`]."]macro_rules!rand{(@assert$p:pat)=>{};(@assert$($p:tt)*)=>{::std::compile_error!(::std::concat!("expected pattern, found `",::std::stringify!($($p)*),"`"));};(@pat$rng:expr,[][])=>{};(@pat$rng:expr,[][],$($t:tt)*)=>{$crate::rand!(@pat$rng,[][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][]$x:ident$($t:tt)*)=>{$crate::rand!(@pat$rng,[$($p)*$x][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][]::$($t:tt)*)=>{$crate::rand!(@pat$rng,[$($p)*::][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][]&$($t:tt)*)=>{$crate::rand!(@pat$rng,[$($p)*&][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][]($($x:tt)*)$($t:tt)*)=>{$crate::rand!(@pat$rng,[$($p)*($($x)*)][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][][$($x:tt)*]$($t:tt)*)=>{$crate::rand!(@pat$rng,[$($p)*[$($x)*]][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][]{$($x:tt)*}$($t:tt)*)=>{$crate::rand!(@pat$rng,[$($p)*{$($x)*}][]$($t)*)};(@pat$rng:expr,[$($p:tt)*][]:$($t:tt)*)=>{$crate::rand!(@ty$rng,[$($p)*][]$($t)*)};(@ty$rng:expr,[$($p:tt)*][$($tt:tt)*]($($x:tt)*)$(,$($t:tt)*)?)=>{$crate::rand!(@let$rng,[$($p)*][$($tt)*($($x)*)]$(,$($t)*)?)};(@ty$rng:expr,[$($p:tt)*][$($tt:tt)*][$($x:tt)*]$(,$($t:tt)*)?)=>{$crate::rand!(@let$rng,[$($p)*][$($tt)*[$($x)*]]$(,$($t)*)?)};(@ty$rng:expr,[$($p:tt)*][$($tt:tt)*]$e:expr)=>{$crate::rand!(@let$rng,[$($p)*][$($tt)*$e])};(@ty$rng:expr,[$($p:tt)*][$($tt:tt)*]$e:expr,$($t:tt)*)=>{$crate::rand!(@let$rng,[$($p)*][$($tt)*$e],$($t)*)};(@ty$rng:expr,[$($p:tt)*][$($tt:tt)*]$e:tt)=>{$crate::rand!(@let$rng,[$($p)*][$($tt)*$e])};(@ty$rng:expr,[$($p:tt)*][$($tt:tt)*]$e:tt,$($t:tt)*)=>{$crate::rand!(@let$rng,[$($p)*][$($tt)*$e],$($t)*)};(@let$rng:expr,[$($p:tt)*][$($tt:tt)*]$($t:tt)*)=>{$crate::rand!{@assert$($p)*}let$($p)* =$crate::rand_value!($rng,$($tt)*);$crate::rand!(@pat$rng,[][]$($t)*)};($rng:expr)=>{};($rng:expr,$($t:tt)*)=>{$crate::rand!(@pat$rng,[][]$($t)*)};}} // codesnip-guard: Xorshift #[cfg_attr(any(),rustfmt::skip)]pub use self::xorshift::Xorshift;#[cfg_attr(any(),rustfmt::skip)]mod xorshift{use std::{collections::hash_map::RandomState,hash::{BuildHasher,Hasher},iter::repeat_with};#[derive(Clone,Debug)]pub struct Xorshift{y:u64}impl Xorshift{pub fn new_with_seed(seed:u64)->Self{Xorshift{y:seed}}pub fn new()->Self{Xorshift::new_with_seed(RandomState::new().build_hasher().finish())}pub fn rand64(&mut self)->u64{self.y^=self.y<<5;self.y^=self.y>>17;self.y^=self.y<<11;self.y}pub fn rand(&mut self,k:u64)->u64{self.rand64()%k}pub fn rands(&mut self,k:u64,n:usize)->Vec{repeat_with(| |self.rand(k)).take(n).collect()}pub fn randf(&mut self)->f64{const UPPER_MASK:u64=0x3FF0_0000_0000_0000;const LOWER_MASK:u64=0x000F_FFFF_FFFF_FFFF;let x=self.rand64();let tmp=UPPER_MASK|(x&LOWER_MASK);let result:f64=f64::from_bits(tmp);f64::from_bits(f64::to_bits(result-1.0)^(x>>63))}pub fn gen_bool(&mut self,p:f64)->bool{self.randf()(&mut self,slice:&mut[T]){let mut n=slice.len();while n>1{let i=self.rand(n as _)as usize;n-=1;slice.swap(i,n);}}}impl Default for Xorshift{fn default()->Self{Xorshift::new_with_seed(0x2b99_2ddf_a232_49d6)}}}