1use crate::util::iter::*;
3use crate::util::parse::*;
4
5pub struct Game(u32, u32, u32);
6
7pub fn parse(input: &str) -> Vec<Game> {
9 input
10 .lines()
11 .map(|line| {
12 line.split_ascii_whitespace().chunk::<2>().skip(1).fold(
13 Game(0, 0, 0),
14 |Game(r, g, b), [amount, color]| {
15 let amount = amount.unsigned();
16 match color.as_bytes()[0] {
17 b'r' => Game(r.max(amount), g, b),
18 b'g' => Game(r, g.max(amount), b),
19 b'b' => Game(r, g, b.max(amount)),
20 _ => unreachable!(),
21 }
22 },
23 )
24 })
25 .collect()
26}
27
28pub fn part1(input: &[Game]) -> usize {
30 input
31 .iter()
32 .enumerate()
33 .filter_map(|(id, &Game(r, g, b))| (r <= 12 && g <= 13 && b <= 14).then_some(id + 1))
34 .sum()
35}
36
37pub fn part2(input: &[Game]) -> u32 {
39 input.iter().map(|Game(r, g, b)| r * g * b).sum()
40}