use std::collections::HashMap; use regex::Regex; pub fn run() { let input = include_str!("../input/day2.txt"); // let input = r#" // 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 games = parse_games(input); let valid_ids_sum: u32 = games .iter() .filter(|g| g.valid_counts(12, 13, 14)) .map(|g| g.id) .sum(); dbg!(valid_ids_sum); let min_counts_power_sum: u32 = games .iter() .map(|g| { let (r, g, b) = g.min_counts(); r * g * b }) .sum(); dbg!(min_counts_power_sum); } fn parse_games(s: &str) -> Vec { let mut games = vec![]; for l in s.lines() { let l = l.trim(); if l.is_empty() { continue; } let (game_s, rest) = l.split_once(": ").unwrap(); let game_n: u32 = game_s .strip_prefix("Game ") .expect("game prefix") .parse() .expect("game number"); let mut draws = vec![]; for draw in rest.split(";") { let drawn = draw .split(", ") .map(|s| { let (count, color) = s.trim().split_once(" ").unwrap(); let count: u32 = count.parse().expect("count number"); (color, count) }) .collect::>(); draws.push(Draw { red: *drawn.get("red").unwrap_or(&0), green: *drawn.get("green").unwrap_or(&0), blue: *drawn.get("blue").unwrap_or(&0), }); } games.push(Game { id: game_n, draws }); } games } #[derive(Debug, Clone)] struct Game { id: u32, draws: Vec, } #[derive(Debug, Copy, Clone)] struct Draw { red: u32, green: u32, blue: u32, } impl Game { fn valid_counts(&self, red: u32, green: u32, blue: u32) -> bool { self.draws .iter() .all(|draw| draw.red <= red && draw.green <= green && draw.blue <= blue) } fn min_counts(&self) -> (u32, u32, u32) { let mut red = 0u32; let mut green = 0u32; let mut blue = 0u32; for draw in self.draws.iter() { red = red.max(draw.red); green = green.max(draw.green); blue = blue.max(draw.blue); } (red, green, blue) } }