summaryrefslogtreecommitdiff
path: root/aoc02/src/main.rs
blob: b8b5eae129f7775ca659d34c33a845cb18866032 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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::<u32>().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::<u32>().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::<u32>().expect("input id not integers"));
        } else if b_mode {
            possibilities.push(rounds_power(rounds));
        }
    }

    println!("{}", possibilities.iter().sum::<u32>());
}