use rand::seq::SliceRandom;
use rand::Rng;
pub fn randrange(lo: i32, hi: i32) -> i32 {
rand::thread_rng().gen_range(lo..hi)
}
pub fn randint(lo: i32, hi: i32) -> i32 {
rand::thread_rng().gen_range(lo..=hi)
}
pub fn shuffle<T>(v: &mut [T]) {
let mut rng = rand::thread_rng();
v.shuffle(&mut rng);
}
pub fn random() -> f64 {
let mut rng = rand::thread_rng();
rng.gen::<f64>()
}
pub fn choice<T>(v: &[T]) -> Option<&T> {
if v.is_empty() {
return None;
}
let idx = randrange(0, v.len() as i32) as usize;
Some(&v[idx])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn randrange_test1() {
for _ in 0..10 {
let value = randrange(1, 2);
assert!(value == 1);
}
for _ in 0..10 {
let value = randrange(1, 3);
assert!(value == 1 || value == 2);
}
for _ in 0..1000 {
let value = randrange(1, 10);
assert!(value >= 1 && value < 10);
}
}
#[test]
fn randint_test1() {
for _ in 0..10 {
let value = randint(1, 1);
assert!(value == 1);
}
for _ in 0..10 {
let value = randint(1, 2);
assert!(value >= 1 && value <= 2);
}
for _ in 0..1000 {
let value = randint(1, 10);
assert!(value >= 1 && value <= 10);
}
}
#[test]
fn randrange_test2() {
let mut v = vec![];
for _ in 0..1000 {
let value = randrange(1, 10);
v.push(value);
}
v.sort();
v.dedup();
for i in 1..=9 {
assert!(v.contains(&i));
}
assert_eq!(v.contains(&0), false);
assert_eq!(v.contains(&10), false);
assert!(v[0] == 1);
assert!(v[v.len() - 1] == 9);
}
#[test]
fn randint_test2() {
let mut v = vec![];
for _ in 0..1000 {
let value = randint(1, 10);
v.push(value);
}
v.sort();
v.dedup();
for i in 1..=10 {
assert!(v.contains(&i));
}
assert_eq!(v.contains(&0), false);
assert_eq!(v.contains(&11), false);
assert!(v[0] == 1);
assert!(v[v.len() - 1] == 10);
}
#[test]
fn shuffle_test1() {
let mut v = vec![];
for i in 1..=100 {
v.push(i);
}
assert!(v.len() == 100);
let backup = v.clone();
shuffle(&mut v);
assert!(v.len() == backup.len());
assert!(v != backup);
v.sort();
assert!(v == backup);
}
#[test]
fn random_test1() {
for _ in 0..100 {
let number = random();
assert!(number >= 0.0 && number < 1.0)
}
}
#[test]
fn choice_test1() {
let v = vec![1, 2, 3];
for _ in 0..100 {
let &elem = choice(&v).unwrap();
assert!(v.contains(&elem));
}
}
#[test]
fn choice_test2() {
let empty = Vec::<i32>::new();
let elem = choice(&empty);
assert_eq!(elem, None);
}
}