1use std::collections::HashMap;
2use utils::prelude::*;
3
4#[derive(Clone, Debug)]
6pub struct Day08 {
7 part1: i32,
8 part2: i32,
9}
10
11impl Day08 {
12 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
13 let parse_iterator = parser::take_while1(u8::is_ascii_lowercase)
14 .with_suffix(" ")
15 .then(
16 parser::one_of((
17 parser::i32().with_prefix("inc "),
18 parser::i32().with_prefix("dec ").map(|x| -x),
19 ))
20 .with_suffix(" if "),
21 )
22 .then(parser::take_while1(u8::is_ascii_lowercase).with_suffix(" "))
23 .then(
24 parser::literal_map!(
25 "==" => i32::eq as fn(&i32, &i32) -> bool,
26 "!=" => i32::ne as fn(&i32, &i32) -> bool,
27 "<=" => i32::le as fn(&i32, &i32) -> bool,
28 ">=" => i32::ge as fn(&i32, &i32) -> bool,
29 "<" => i32::lt as fn(&i32, &i32) -> bool,
30 ">" => i32::gt as fn(&i32, &i32) -> bool,
31 )
32 .with_suffix(" "),
33 )
34 .then(parser::i32())
35 .with_suffix(parser::eol())
36 .parse_iterator(input);
37
38 let mut registers = HashMap::new();
39 let mut max = 0;
40 for item in parse_iterator {
41 let (reg, value, cond_reg, comparison, cond_value) = item?;
42 if comparison(registers.entry(cond_reg).or_insert(0), &cond_value) {
43 let entry = registers.entry(reg).or_insert(0);
44 *entry += value;
45 max = max.max(*entry);
46 }
47 }
48
49 Ok(Self {
50 part1: registers.into_values().max().unwrap_or(0),
51 part2: max,
52 })
53 }
54
55 #[must_use]
56 pub fn part1(&self) -> i32 {
57 self.part1
58 }
59
60 #[must_use]
61 pub fn part2(&self) -> i32 {
62 self.part2
63 }
64}
65
66examples!(Day08 -> (i32, i32) [
67 {
68 input: "b inc 5 if a > 1\n\
69 a inc 1 if b < 5\n\
70 c dec -10 if a >= 1\n\
71 c inc -20 if c == 10",
72 part1: 1,
73 part2: 10
74 },
75]);