#[derive(Debug)] struct GameSet { red: u32, green: u32, blue: u32 } fn normalize(x: u32) -> u32 { if x == 0 { 1 } else { x } } impl GameSet { fn power(&self) -> u32 { normalize(self.red) * normalize(self.green) * normalize(self.blue) } } struct Game { id: u32, sets: Vec } impl Game { fn min_gameset(&self) -> GameSet { let mut red = 0; let mut green = 0; let mut blue = 0; for gameset in self.sets.iter() { if gameset.red > 0 { red = u32::max(red, gameset.red); } if gameset.green > 0 { green = u32::max(green, gameset.green); } if gameset.blue > 0 { blue = u32::max(blue, gameset.blue); } } GameSet { red, green, blue } } } fn main() { let input = include_str!("./input.txt"); let output: u32 = input .lines() .map(|line| { process_line(line) }) .map(|game| { game.min_gameset().power() }) .sum(); println!("Result {output}") } fn gameset_from_pairs(pairs: Vec<(&str, u32)>) -> GameSet { let mut red: u32 = 0; let mut green: u32 = 0; let mut blue: u32 = 0; for pair in pairs { match pair { ("red", x) => { red = x }, ("green", x) => { green = x }, ("blue", x) => { blue = x }, what => panic!("Unknown pair {:?}", what) } } GameSet { red, green, blue } } /// Progrss a line fn process_line(string: &str) -> Game { let game_split: Vec<&str> = string.splitn(2, ": ").collect(); // Get game Id from string "Game 1" let game_id = game_split[0].split(" ").last().expect("Expected id").parse::().expect("Cant parse game id"); let sets: Vec<_> = game_split[1] .split("; ") .map(|set_line| { set_line.split(", ").collect() }) .map(|gameset: Vec<&str>| { let pairs: Vec<(&str, u32)> = gameset.into_iter().map(|s| { let split: Vec<&str> = s.split_whitespace().collect(); (split[1], split[0].parse::().expect("Cant parse")) }).collect(); gameset_from_pairs(pairs) }) .collect(); Game { id: game_id, sets } } #[cfg(test)] mod tests { use super::*; #[test] fn test_process_simple() { let game = process_line("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green"); assert_eq!(game.id, 1); } #[test] fn test_input() { let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"; let output: u32 = input .lines() .map(|line| { process_line(line) }) .map(|game| { game.min_gameset() }) .inspect(|power| { dbg!(power); }) .map(|gs| { gs.power() }) .sum(); assert_eq!(output, 2286); } }