use std::{path::Path, str::FromStr, cmp::max}; use crate::input::{AdventError, read_into_vec}; impl FromStr for Color { type Err = AdventError; fn from_str(s: &str) -> Result { Ok(match s { "red" => Color::Red, "green" => Color::Green, "blue" => Color::Blue, _ => return Err(AdventError("No matching Color enum.".to_string())) }) } } impl FromStr for Group { type Err = AdventError; fn from_str(s: &str) -> Result { let split = s.split(' ').collect::>(); Ok(Group{count: u32::from_str(split[0])?, color: Color::from_str(split[1])?}) } } impl FromStr for Pull { type Err = AdventError; fn from_str(s: &str) -> Result { let mut res = Vec::::new(); for group in s.split(';') { let group = group.trim(); res.push(Group::from_str(group)?); } Ok(Pull{groups: res}) } } impl FromStr for Game { type Err = AdventError; fn from_str(s: &str) -> Result { let split = s.split(':').collect::>(); let id = u32::from_str(split[0].split(' ').collect::>()[1])?; let pulls = split[1]; let mut res = Vec::::new(); for pull in pulls.split(',') { let pull = pull.trim(); res.push(Pull::from_str(pull)?); } Ok(Game{id: id, pulls: res}) } } #[derive(Debug)] enum Color { Red, Green, Blue } #[derive(Debug)] struct Group { count: u32, color: Color, } #[derive(Debug)] struct Pull { groups: Vec } #[derive(Debug)] struct Game { id: u32, pulls: Vec } pub fn one() -> Result<(), AdventError> { let games: Vec = read_into_vec(Path::new("resources/input2.txt"))?; let mut sum: u32 = 0; let max_red = 12; let max_green = 13; let max_blue = 14; for game in games.iter() { if game.pulls.iter().all(|pull| { pull.groups.iter().all(|group| { match group.color { Color::Red => group.count <= max_red, Color::Green => group.count <= max_green, Color::Blue => group.count <= max_blue, } }) }) { sum += game.id } } Ok(println!("{}", sum)) } pub fn two() -> Result<(), AdventError> { let games: Vec = read_into_vec(Path::new("resources/input2.txt"))?; let mut power: u32 = 0; for game in games.iter() { let mut max_nr_red = 0; let mut max_nr_green = 0; let mut max_nr_blue = 0; for pull in game.pulls.iter() { for group in pull.groups.iter() { match group.color { Color::Red => max_nr_red = max(max_nr_red, group.count), Color::Green => max_nr_green = max(max_nr_green, group.count), Color::Blue => max_nr_blue = max(max_nr_blue, group.count) } } } power += max_nr_red * max_nr_green * max_nr_blue; } Ok(println!("{}", power)) }