use std::{collections::BTreeMap, env::args, io::stdin}; fn rounds_are_possible(rounds: &str) -> bool { !rounds .split(&[';', ',']) .map(|round| round.trim().split_once(' ').expect("bad input whitespace")) .map(|(score, color)| (score.parse::().expect("input score not digit"), color)) .map(|(score, color)| { color == "red" && score > 12 || color == "blue" && score > 14 || color == "green" && score > 13 }) .any(|p| p) } fn rounds_power(rounds: &str) -> u32 { let mut maximums = BTreeMap::new(); for (score, color) in rounds .split(&[';', ',']) .map(|round| round.trim().split_once(' ').expect("bad input whitespace")) .map(|(score, color)| (score.parse::().expect("input score not digit"), color)) { if &score > maximums.get(color).unwrap_or(&0) { maximums.insert(color, score); } } maximums.values().product() } fn main() { let b_mode = args().any(|b| b == "-b"); let mut lines = stdin().lines(); let mut possibilities = Vec::new(); while let Some(Ok(line)) = lines.next() { let line = line .strip_prefix("Game ") .expect("input missing game prefix"); let (id, rounds) = line .split_once(": ") .expect("input missing colon separator"); if !b_mode && rounds_are_possible(rounds) { possibilities.push(id.parse::().expect("input id not integers")); } else if b_mode { possibilities.push(rounds_power(rounds)); } } println!("{}", possibilities.iter().sum::()); }