aoc/year2023/
day02.rs

1//! # Cube Conundrum
2use crate::util::iter::*;
3use crate::util::parse::*;
4
5pub struct Game(u32, u32, u32);
6
7/// Parse each game into the maximum red, green and blue values.
8pub 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
28/// Sum the ids for all valid games.
29pub 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
37/// Sum the product of maximum red, green and blue values.
38pub fn part2(input: &[Game]) -> u32 {
39    input.iter().map(|Game(r, g, b)| r * g * b).sum()
40}