#![allow(dead_code)] use rand::prelude::*; // includes `use rand::{Rng, SeedableRng, rngs::StdRng};` //use rand::rngs::mock::StepRng; fn main() { print_samples(); } /// return the maximum of `k` draws from the interval `[0,n)`, /// using `rng` to generate the numbers. /// /// pre-condition: k > 0, n > 0. /// // design note: In rust, *ranges* are valid values; // it'd be more general to, instead of passing n, passing in an entire Range. // (However, bug(?): StepRng.randomRange() doesn't work!?!, so we use %n instead.) fn max_of_rands(n: u64, k: u64, rng: &mut T) -> u64 { //let mut my_rng = rand::rngs::StdRng::seed_from_u64(seed); let mut max_so_far = 0_u64; assert!(k > 0); assert!(n > 0); for _ in 0..k { max_so_far = std::cmp::max(max_so_far, rng.random::() % n); } max_so_far } // not a #[test], because it prints rather than asserts. fn print_samples() -> () { let mut predictable = rand::rngs::mock::StepRng::new(7, 3); // generates: 7, 10, 13, 16, … println!("predictably 7: {}", predictable.random::() % 20); println!("predictably 10: {}", predictable.random::() % 20); println!("predictably 13: {}", predictable.random::() % 20); //let mut rng1 = rand::rngs::StdRng::seed_from_u64(2025); //println!("random #1 w/ seed 2025: {}", rng1.random::() % 20 ); //println!("random #2 w/ seed 2025: {}", rng1.random::() % 20 ); let mut rng1 = rand::rngs::StdRng::seed_from_u64(2025); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); println!("max of 2 d20s: {}", max_of_rands(20, 2, &mut rng1)); let mut rng1 = StdRng::seed_from_u64(2025); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); println!("max of 3 d20s: {}", max_of_rands(20, 3, &mut rng1)); } #[test] #[allow(unused_comparisons)] // in case we test 0 <= some_u64. fn test_max_of_rands() -> () { let mut predictable = rand::rngs::mock::StepRng::new(7, 3); // generates: 7, 10, 13, 16, … assert_eq!(max_of_rands(20, 1, &mut predictable), 7); assert_eq!(max_of_rands(20, 1, &mut predictable), 10); assert_eq!(max_of_rands(20, 1, &mut predictable), 13); assert_eq!(max_of_rands(20, 1, &mut predictable), 16); assert_eq!(max_of_rands(20, 1, &mut predictable), 19); assert_eq!(max_of_rands(20, 1, &mut predictable), 2); // Samples of size 2 let mut predictable = rand::rngs::mock::StepRng::new(7, 3); // generates: 7, 10, 13, 16, … assert_eq!(max_of_rands(20, 2, &mut predictable), 10); // out of 7,10 assert_eq!(max_of_rands(20, 2, &mut predictable), 16); // out of 13,16 assert_eq!(max_of_rands(20, 2, &mut predictable), 19); // out of 19,2 assert_eq!(max_of_rands(20, 2, &mut predictable), 8); // out of 5,8 // Samples of size many. Er, size 3. let mut predictable = rand::rngs::mock::StepRng::new(7, 3); // generates: 7, 10, 13, 16, … assert_eq!(max_of_rands(20, 3, &mut predictable), 13); // out of 7,10,13 assert_eq!(max_of_rands(20, 3, &mut predictable), 19); // out of 16,19,2 assert_eq!(max_of_rands(20, 3, &mut predictable), 11); // out of 5,8,11 for seed in 30..200 { // Try many different seeds; we'll just assert that the result is in 0..20 // (not a great test, but it's all we can say for sure). let max_of_2_samples = max_of_rands(20, 2, &mut StdRng::seed_from_u64(seed)); assert!(0 <= max_of_2_samples); assert!(max_of_2_samples < 20); // We can actually use a range's `contains`, to do the above 2 asserts at once: assert!((0..20).contains(&max_of_2_samples)); } }