aoc/year2017/
day08.rs

1//! # I Heard You Like Registers
2//!
3//! Computes both parts in a single pass. Each register name is between one and three letters,
4//! so we use a base 27 index (counting `a` as 1 and a blank space as 0) into a `vec` which is
5//! faster than using a hashmap.
6use 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 [a, b, c, _, e, f, g] in input.split_ascii_whitespace().chunk::<7>() {
16        let first = registers[to_index(e)];
17        let second: i32 = g.signed();
18
19        let predicate = match f {
20            "==" => first == second,
21            "!=" => first != second,
22            ">=" => first >= second,
23            "<=" => first <= second,
24            ">" => first > second,
25            "<" => first < second,
26            _ => unreachable!(),
27        };
28
29        if predicate {
30            let third = &mut registers[to_index(a)];
31            let fourth: i32 = c.signed();
32
33            match b {
34                "inc" => *third += fourth,
35                "dec" => *third -= fourth,
36                _ => unreachable!(),
37            }
38
39            part_two = part_two.max(*third);
40        }
41    }
42
43    let part_one = registers.into_iter().max().unwrap();
44    (part_one, part_two)
45}
46
47pub fn part1(input: &Input) -> i32 {
48    input.0
49}
50
51pub fn part2(input: &Input) -> i32 {
52    input.1
53}
54
55fn to_index(s: &str) -> usize {
56    s.bytes().fold(0, |acc, b| 27 * acc + usize::from(b - b'a' + 1))
57}