use std::io::{self, Read}; #[derive(Debug)] struct Game { #[allow(unused)] id: u32, matches: Vec, } impl Game { fn min_match(&self) -> Match { self.matches.iter().fold(Match(0, 0, 0), |acc, m| { let mut red = acc.0; let mut green = acc.1; let mut blue = acc.2; if m.0 > red { red = m.0; } if m.1 > green { green = m.1; } if m.2 > blue { blue = m.2; } Match(red, green, blue) }) } } #[derive(Debug)] struct Match(u32, u32, u32); impl Match { fn power(&self) -> u32 { self.0 * self.1 * self.2 } } fn main() { let mut buf = String::new(); io::stdin().read_to_string(&mut buf).unwrap(); let lines: Vec = buf.lines().map(ToOwned::to_owned).collect(); let answer: u32 = lines .iter() .map(|l| &l[4..]) .map(|l| l.split(':').map(str::trim).collect::>()) .map(|l| Game { id: l[0].parse().unwrap(), matches: l[1] .split(';') .map(str::trim) .map(|round| { round .split(',') .map(str::trim) .map(|cubes| cubes.split(' ').collect::>()) .fold(Match(0, 0, 0), |acc, cube_count| match cube_count[1] { "red" => Match(cube_count[0].parse().unwrap(), acc.1, acc.2), "green" => Match(acc.0, cube_count[0].parse().unwrap(), acc.2), "blue" => Match(acc.0, acc.1, cube_count[0].parse().unwrap()), _ => acc, }) }) .collect(), }) .map(|g| g.min_match()) .map(|m| m.power()) .sum(); print!("{answer}") }