day2: [rust] added formatting and comparison operators
authorPat Thoyts <pat.thoyts@gmail.com>
Sun, 3 Dec 2023 23:54:02 +0000 (23:54 +0000)
committerPat Thoyts <pat.thoyts@gmail.com>
Sun, 3 Dec 2023 23:54:02 +0000 (23:54 +0000)
day2/src/game.rs
day2/src/main.rs
day2/src/round.rs

index 37de463b9a01bbc05527c0115484e4f2efca6291..a716e68af235b52f23360e9631ce909709f3106d 100644 (file)
@@ -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));
+    }
 }
index 24f4ce561c17e3afc5d9459035dc7edff7be0499..fca5d40b0590f7700da4e52ff0a0fa488c627fc1 100644 (file)
@@ -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<dyn Error>> {
     let args: Vec<String> = env::args().collect();
@@ -43,8 +24,8 @@ fn main() -> Result<(), Box<dyn Error>> {
 
         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);
index 0b01fc7dacb69aef719f9a1d034cee4bff74601f..6c7945eaa71c6d67ef1116e9a38450034db270fb 100644 (file)
@@ -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::<String>::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);
+    }
 }