struct GameSet { red: u32, green: u32, blue: u32 } impl GameSet { fn is_valid(&self) -> bool { self.red <= 12 && self.green <= 13 && self.blue <= 14 } } struct Game { id: u32, sets: Vec } fn main() { let input = include_str!("./input.txt"); let output: u32 = input .lines() .map(|line| { process_line(line) }) .filter(|game| { game.sets.iter().all(|set: &GameSet| set.is_valid()) }) .map(|game| { game.id }).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) }) .filter(|game| { game.sets.iter().all(|set: &GameSet| set.is_valid()) }) .map(|game| { game.id }).sum(); assert_eq!(output, 8); } }