diff --git a/src/euler84/src/lib.rs b/src/euler84/src/lib.rs index 7f877a9..2694a51 100644 --- a/src/euler84/src/lib.rs +++ b/src/euler84/src/lib.rs @@ -1,13 +1,14 @@ -use std::collections::{HashMap, VecDeque}; +use std::collections::VecDeque; use std::fmt::Display; use std::iter::Cycle; use rand::prelude::*; -use rand::seq::IteratorRandom; use strum::IntoEnumIterator; use strum_macros::EnumIter; const NUMBER_SQUARES: usize = 40; +const FOUR: [usize; 4] = [1, 2, 3, 4]; +const SIX: [usize; 6] = [1, 2, 3, 4, 5, 6]; #[derive(Debug, EnumIter, PartialEq, Hash, Eq, PartialOrd)] pub enum Squares { @@ -53,7 +54,7 @@ pub enum Squares { H2 = 39, } -#[derive(Debug, EnumIter, Clone)] +#[derive(Debug, EnumIter)] enum CommunityChest { AdvanceToGo, GoToJail, @@ -73,7 +74,7 @@ enum CommunityChest { DoNothing14, } -#[derive(Debug, EnumIter, Clone)] +#[derive(Debug, EnumIter)] enum Chance { AdvanceToGo, GoToJail, @@ -104,18 +105,17 @@ impl Display for Squares { } } -#[allow(dead_code)] #[derive(Debug)] pub enum Dice { - FourSided = 4, - SixSided = 6, + FourSided, + SixSided, } impl Dice { fn throw(&self, rng: &mut ThreadRng) -> usize { match self { - Self::SixSided => (1..=6).choose(rng).unwrap() as usize, - Self::FourSided => (1..=4).choose(rng).unwrap() as usize, + Self::SixSided => *SIX.choose(rng).unwrap(), + Self::FourSided => *FOUR.choose(rng).unwrap(), } } } @@ -131,14 +131,12 @@ pub struct Monopoly { impl Monopoly { fn throw_dice(&mut self) -> (usize, bool) { - let mut iter = (0..2).map(|_| self.dice.throw(&mut self.rng)); - let t1 = iter.next().unwrap(); - let t2 = iter.next().unwrap(); + let t1 = self.dice.throw(&mut self.rng); + let t2 = self.dice.throw(&mut self.rng); let is_double = t1 == t2; (t1 + t2, is_double) } - #[allow(clippy::new_without_default)] pub fn new(dice: Dice) -> Self { let mut rng = rand::thread_rng(); let community_pile = Self::gen_random_community_pile(&mut rng); @@ -188,7 +186,7 @@ impl Monopoly { } fn go_to_jail(&mut self) -> Squares { - self.go_to_square(Squares::Jail) + self.go_to_square(&Squares::Jail) } fn handle_chance(&mut self, square: Squares) -> Squares { @@ -196,10 +194,10 @@ impl Monopoly { match card { Chance::AdvanceToGo => self.advance_to_go(), Chance::GoToJail => self.go_to_jail(), - Chance::GoToC1 => self.go_to_square(Squares::C1), - Chance::GoToE3 => self.go_to_square(Squares::E3), - Chance::GoToH2 => self.go_to_square(Squares::H2), - Chance::GoToR1 => self.go_to_square(Squares::R1), + Chance::GoToC1 => self.go_to_square(&Squares::C1), + Chance::GoToE3 => self.go_to_square(&Squares::E3), + Chance::GoToH2 => self.go_to_square(&Squares::H2), + Chance::GoToR1 => self.go_to_square(&Squares::R1), Chance::GoToNextR | Chance::GoToNextRAgain => self.go_to_railway(), Chance::GoToNextU => self.go_to_utility(), Chance::GoBack3Squares => self.go_back_3_squares(), @@ -207,8 +205,8 @@ impl Monopoly { } } - fn go_to_square(&mut self, square: Squares) -> Squares { - self.board.find(|c| *c == square).unwrap() + fn go_to_square(&mut self, square: &Squares) -> Squares { + self.board.find(|c| c == square).unwrap() } fn go_to_squares(&mut self, squares: &[Squares]) -> Squares { @@ -227,7 +225,7 @@ impl Monopoly { } fn advance_to_go(&mut self) -> Squares { - self.go_to_square(Squares::Go) + self.go_to_square(&Squares::Go) } fn draw_from_chance_pile_and_put_at_bottom(&mut self) -> &Chance { @@ -257,7 +255,8 @@ impl Monopoly { fn check_too_many_doubles(&mut self, is_double: bool) -> bool { if is_double { self.number_consecutive_doubles += 1; - self.number_consecutive_doubles == 3 + self.number_consecutive_doubles %= 3; + self.number_consecutive_doubles == 0 } else { self.number_consecutive_doubles = 0; false @@ -272,7 +271,7 @@ impl Monopoly { pub struct Statistics { monopoly: Monopoly, iterations: usize, - fields_count: HashMap, + fields_count: Vec, } impl Statistics { @@ -280,21 +279,20 @@ impl Statistics { Self { monopoly, iterations, - fields_count: Squares::iter().zip([0].into_iter().cycle()).collect(), + fields_count: vec![0; 40], } } pub fn run(&mut self) { for _ in 0..self.iterations { let square = self.monopoly.make_move(); - *self.fields_count.get_mut(&square).unwrap() += 1; + self.fields_count[square as isize as usize] += 1; } } pub fn show(&self) { - let mut result: Vec<(&Squares, f64)> = self - .fields_count - .iter() + let mut result: Vec<(Squares, f64)> = Squares::iter() + .zip(&self.fields_count) .map(|(k, v)| (k, *v as f64 / self.iterations as f64 * 100.)) .collect(); result.sort_unstable_by(|(_, v1), (_, v2)| v2.partial_cmp(v1).unwrap()); @@ -355,7 +353,7 @@ mod test { #[test] fn custom() { let mut monopoly = Monopoly::new(Dice::SixSided); - assert_eq!(monopoly.go_to_square(Squares::E3), Squares::E3); + assert_eq!(monopoly.go_to_square(&Squares::E3), Squares::E3); assert_eq!(monopoly.advance_by(1), Squares::R3); } diff --git a/src/euler84/src/main.rs b/src/euler84/src/main.rs index ed0dd20..131e264 100644 --- a/src/euler84/src/main.rs +++ b/src/euler84/src/main.rs @@ -2,7 +2,7 @@ use euler84::{Dice, Monopoly, Statistics}; fn main() { let monopoly = Monopoly::new(Dice::FourSided); - let mut statistics = Statistics::new(monopoly, 500_000_000); + let mut statistics = Statistics::new(monopoly, 10_000_000); statistics.run(); statistics.show(); }