1use crate::util::iter::*;
7use crate::util::parse::*;
8
9type Input = (i32, i32);
10
11pub fn parse(input: &str) -> Input {
12 let mut registers = vec![0; 27 * 27 * 27];
13 let mut part_two = 0;
14
15 for [target, operation, amount, _, source, comparison, threshold] in
16 input.split_ascii_whitespace().chunk::<7>()
17 {
18 let value = registers[to_index(source)];
19 let threshold = threshold.signed();
20
21 let predicate = match comparison {
22 "==" => value == threshold,
23 "!=" => value != threshold,
24 ">=" => value >= threshold,
25 "<=" => value <= threshold,
26 ">" => value > threshold,
27 "<" => value < threshold,
28 _ => unreachable!(),
29 };
30
31 if predicate {
32 let register = &mut registers[to_index(target)];
33 let amount: i32 = amount.signed();
34
35 match operation {
36 "inc" => *register += amount,
37 "dec" => *register -= amount,
38 _ => unreachable!(),
39 }
40
41 part_two = part_two.max(*register);
42 }
43 }
44
45 let part_one = registers.into_iter().max().unwrap();
46 (part_one, part_two)
47}
48
49pub fn part1(input: &Input) -> i32 {
50 input.0
51}
52
53pub fn part2(input: &Input) -> i32 {
54 input.1
55}
56
57fn to_index(s: &str) -> usize {
58 s.bytes().fold(0, |acc, b| 27 * acc + usize::from(b - b'a' + 1))
59}