aoc/year2015/
day08.rs

1//! # Matchsticks
2//!
3//! While [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) may feel like a
4//! natural choice, it's much faster and easier to simply treat the input as a stream of raw
5//! ASCII `u8` bytes including newlines.
6//!
7//! For part one we run a small state machine using [`fold`] to keep track of the current and
8//! previous characters. If we encounter a hexadecimal escape then four characters become one so the
9//! difference increases by three. The sequences `\\` and `\"` both increase the difference by one.
10//! Each newline increases the difference by two since every line is enclosed with two quotes.
11//!
12//! Part two is even more straightforward with no need for statekeeping. Quotes and backslashes
13//! need to be escaped so increase the difference by one. As before each newline increases by the
14//! difference by two.
15//!
16//! [`fold`]: Iterator::fold
17const NEWLINE: u8 = 10;
18const QUOTE: u8 = 34;
19const SLASH: u8 = 92;
20const ESCAPE: u8 = 120;
21
22pub fn parse(input: &str) -> &str {
23    input
24}
25
26pub fn part1(input: &str) -> u32 {
27    let (_, result) = input.bytes().fold((false, 0), |(flag, count), b| match (flag, b) {
28        (true, ESCAPE) => (false, count + 3),
29        (true, _) => (false, count + 1),
30        (false, SLASH) => (true, count),
31        (false, NEWLINE) => (false, count + 2),
32        _ => (false, count),
33    });
34    result
35}
36
37pub fn part2(input: &str) -> u32 {
38    input
39        .bytes()
40        .map(|b| match b {
41            QUOTE | SLASH => 1,
42            NEWLINE => 2,
43            _ => 0,
44        })
45        .sum()
46}