#![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 `seed` to seed a rng. /// /// pre-condition: k > 0, n > 0. fn max_of_rands(n: u64, k: u64, seed: u64) -> 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 { let next_roll = my_rng.random::() % n; max_so_far = if max_so_far > next_roll { max_so_far } else { next_roll } } max_so_far } // not a #[test], because it prints rather than asserts. fn print_samples() -> () { println!("max of 2 d20s: {}", max_of_rands(20, 2, 2025)); println!("max of 2 d20s: {}", max_of_rands(20, 2, 2026)); println!("max of 2 d20s: {}", max_of_rands(20, 2, 2027)); println!("max of 2 d20s: {}", max_of_rands(20, 2, 2028)); println!("max of 3 d20s: {}", max_of_rands(20, 3, 2025)); println!("max of 3 d20s: {}", max_of_rands(20, 3, 2026)); println!("max of 3 d20s: {}", max_of_rands(20, 3, 2027)); println!("max of 3 d20s: {}", max_of_rands(20, 3, 2028)); } #[test] fn test_max_of_rands() -> () { 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, 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)); } }