aoc/year2016/
day07.rs

1//! # Internet Protocol Version 7
2//!
3//! For part two there are at most 26 * 26 = 676 possible ABA or BAB sequences so we can use
4//! a fixed size array to keep track of which ones we've seen for the current address so far.
5pub fn parse(input: &str) -> Vec<&[u8]> {
6    input.lines().map(str::as_bytes).collect()
7}
8
9pub fn part1(input: &[&[u8]]) -> usize {
10    input
11        .iter()
12        .filter(|line| {
13            let mut has_abba = false;
14            let mut inside_brackets = false;
15
16            for w in line.windows(4) {
17                if w[0].is_ascii_lowercase() {
18                    if w[0] == w[3] && w[1] == w[2] && w[0] != w[1] {
19                        if inside_brackets {
20                            return false;
21                        }
22                        has_abba = true;
23                    }
24                } else {
25                    inside_brackets = w[0] == b'[';
26                }
27            }
28
29            has_abba
30        })
31        .count()
32}
33
34pub fn part2(input: &[&[u8]]) -> usize {
35    let mut aba = [usize::MAX; 676];
36    let mut bab = [usize::MAX; 676];
37
38    input
39        .iter()
40        .enumerate()
41        .filter(|&(version, line)| {
42            let mut inside_brackets = false;
43
44            for w in line.windows(3) {
45                if w[0].is_ascii_lowercase() {
46                    if w[0] == w[2] && w[0] != w[1] && w[1].is_ascii_lowercase() {
47                        let first = (w[0] - b'a') as usize;
48                        let second = (w[1] - b'a') as usize;
49
50                        if inside_brackets {
51                            // Reverse the order of letters
52                            let index = 26 * second + first;
53                            bab[index] = version;
54                            if aba[index] == version {
55                                return true;
56                            }
57                        } else {
58                            let index = 26 * first + second;
59                            aba[index] = version;
60                            if bab[index] == version {
61                                return true;
62                            }
63                        }
64                    }
65                } else {
66                    inside_brackets = w[0] == b'[';
67                }
68            }
69
70            false
71        })
72        .count()
73}