From 89bb3425631c8f02b2e73fc4ca29a09cffd4948d Mon Sep 17 00:00:00 2001 From: Pat Thoyts Date: Sun, 3 Dec 2023 23:54:02 +0000 Subject: [PATCH] day2: [rust] added formatting and comparison operators --- day2/src/game.rs | 25 +++++++++++++++++++++++++ day2/src/main.rs | 25 +++---------------------- day2/src/round.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/day2/src/game.rs b/day2/src/game.rs index 37de463..a716e68 100644 --- a/day2/src/game.rs +++ b/day2/src/game.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use round::Round; use std::cmp; +use std::fmt; #[derive(Debug, PartialEq, Eq)] pub struct Game { @@ -21,6 +22,22 @@ impl Game { } return res.red * res.green * res.blue; } + + pub fn valid(&self, limits: &Round) -> bool { + return self.rounds.iter().all(|r| r <= limits) + } +} + +impl fmt::Display for Game { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Game {}", self.id)?; + let mut joiner = ':'; + for round in &self.rounds { + write!(f, "{} {}", joiner, round)?; + joiner = ';' + } + Ok(()) + } } impl FromStr for Game { @@ -76,4 +93,12 @@ mod tests { let game = Game::from_str("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green").unwrap(); assert_eq!(game.power(), 48); } + + #[test] + fn test_game_fmt() { + let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green"; + let expected = "Game 1: 4 red, 3 blue; 1 red, 2 green, 6 blue; 2 green"; + let game = Game::from_str(input).unwrap(); + assert_eq!(expected, format!("{}", game)); + } } diff --git a/day2/src/main.rs b/day2/src/main.rs index 24f4ce5..fca5d40 100644 --- a/day2/src/main.rs +++ b/day2/src/main.rs @@ -7,26 +7,7 @@ use std::env; use std::error::Error; use std::str::FromStr; use std::fs::File; -use std::io::{BufReader, BufRead}; //, Error}; - -fn valid_round(round: &Round, limits: &Round) -> bool { - return round.red <= limits.red - && round.green <= limits.green - && round.blue <= limits.blue; -} - -fn valid_game(game: &Game, limits: &Round) -> bool { - return game.rounds.iter().all(|x| valid_round(x, limits)) -} - -#[allow(dead_code)] -fn print_game(game: &Game) { - print!("Game {}: ", game.id); - for round in game.rounds.iter() { - print!("{} red, {} green, {} blue;", round.red, round.green, round.blue); - } - println!(""); -} +use std::io::{BufReader, BufRead}; fn main() -> Result<(), Box> { let args: Vec = env::args().collect(); @@ -43,8 +24,8 @@ fn main() -> Result<(), Box> { let limits = Round { red: 12, green: 13, blue: 14 }; let sum_ids: u32 = games.iter() - .filter(|g| valid_game(g, &limits)) - // .inspect(|g| print_game(g)) + .filter(|g| g.valid(&limits)) + // .inspect(|g| println!("{}", g)) .map(|g| g.id) .sum(); println!("part 1: {}", sum_ids); diff --git a/day2/src/round.rs b/day2/src/round.rs index 0b01fc7..6c7945e 100644 --- a/day2/src/round.rs +++ b/day2/src/round.rs @@ -1,6 +1,7 @@ use std::str::FromStr; +use std::fmt; -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Round { pub red: u32, pub green: u32, @@ -10,6 +11,16 @@ pub struct Round { #[derive(Debug, PartialEq, Eq)] pub struct ParseRoundError; +impl fmt::Display for Round { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut vec = Vec::::new(); + if self.red > 0 { vec.push(format!("{} red", self.red)); } + if self.green > 0 { vec.push(format!("{} green", self.green)); } + if self.blue > 0 { vec.push(format!("{} blue", self.blue)); } + write!(f, "{}", vec.join(", ")) + } +} + impl FromStr for Round { type Err = ParseRoundError; @@ -64,4 +75,37 @@ mod tests { fn test_parse_invalid_line() { assert!(Round::from_str("").is_err()); } + + #[test] + fn test_format_round() { + let r = Round { red: 20, green: 2, blue: 5 }; + assert_eq!("20 red, 2 green, 5 blue", + format!("{}", r)); + } + + #[test] + fn test_format_round_zeros() { + let r = Round { red: 0, green: 2, blue: 0 }; + assert_eq!("2 green", format!("{}", r)); + } + + #[test] + fn test_round_eq() { + let a = Round { red: 1, green: 2, blue: 3 }; + let b = Round { red: 1, green: 2, blue: 3 }; + assert!(a == b); + } + + #[test] + fn test_round_lt() { + let a = Round { red: 1, green: 2, blue: 3 }; + let b = Round { red: 1, green: 2, blue: 3 }; + let c = Round { red: 0, green: 1, blue: 1 }; + assert!(b <= a); + assert!(c <= a); + assert!(c < a); + assert!(a > c); + assert!(a != c); + assert_ne!(a, c); + } } -- 2.23.0