summaryrefslogtreecommitdiff
path: root/src/bin/day2.rs
blob: a0071598814cd97c453c9cef48e74f80e6a588fc (plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#![feature(test)]
use std::error::Error;

const COLORS: [&str; 3] = ["red", "green", "blue"];
const AMOUNT: [u32; 3] = [12, 13, 14];

// NOTE: probably should just panic, filter_mapping doesn't make much sense if you need the input to be correct.
fn main() -> Result<(), Box<dyn Error>> {
    let file = std::fs::read_to_string("input/2/in.txt")?;
    let cube_lines: Vec<_> = file
        .lines()
        .enumerate()
        .filter_map(|(i, line)| -> Option<(u32, Vec<(usize, u32)>)> {
            let mut fields = line.split(':');
            let id: u32 = (i + 1) as u32;
            let cubes = fields
                .nth(1)?
                .split(';')
                .flat_map(|s| {
                    s.trim()
                        .split(",")
                        .filter_map(|game| {
                            let mut fields = game.trim().split(" ");
                            let num: u32 = fields.next()?.parse().ok()?;
                            let color = fields.next()?;
                            let c = COLORS.iter().position(|col| *col == color)?;
                            Some((c, num))
                        })
                        .collect::<Vec<_>>()
                })
                .collect();
            Some((id, cubes))
        })
        .collect();

    let part1: u32 = cube_lines
        .iter()
        .filter_map(|(id, cubes)| {
            if cubes.iter().all(|(color, num)| *num <= AMOUNT[*color]) {
                Some(id)
            } else {
                None
            }
        })
        .sum();
    dbg!(part1);
    let part2: u32 = cube_lines
        .iter()
        .map(|(_, cubes)| {
            cubes
                .into_iter()
                .fold([0, 0, 0], |mut acc, (color, num)| {
                    if acc[*color] < *num {
                        acc[*color] = *num;
                    }
                    acc
                })
                .into_iter()
                .product::<u32>()
        })
        .sum();
    dbg!(part2);

    Ok(())
}

extern crate test;

#[cfg(test)]
mod tests {
    use super::*;
    use test::Bencher;

    #[bench]
    fn other(b: &mut Bencher) {
        b.iter(|| main());
    }
}