1pub fn parse(input: &str) -> &[u8] {
9 input.as_bytes()
10}
11
12pub fn part1(input: &[u8]) -> usize {
13 let mut count = 0;
14 let mut inside = false;
15 let mut positive = false;
16 let mut negative = false;
17
18 for w in input.windows(4) {
19 if w[0].is_ascii_lowercase() {
20 if w[0] == w[3] && w[1] == w[2] && w[0] != w[1] {
21 if inside {
22 negative = true;
23 } else {
24 positive = true;
25 }
26 }
27 } else if w[0] == b'[' {
28 inside = true;
29 } else if w[0] == b']' {
30 inside = false;
31 } else {
32 if positive && !negative {
34 count += 1;
35 }
36 positive = false;
37 negative = false;
38 }
39 }
40
41 if positive && !negative { count + 1 } else { count }
42}
43
44pub fn part2(input: &[u8]) -> usize {
45 let mut count = 0;
46 let mut version = 0;
47 let mut inside = false;
48 let mut positive = false;
49 let mut aba = [usize::MAX; 676];
50 let mut bab = [usize::MAX; 676];
51
52 for w in input.windows(3) {
53 if w[1].is_ascii_lowercase() {
54 if w[0] == w[2] && w[0] != w[1] {
55 let first = (w[0] - b'a') as usize;
56 let second = (w[1] - b'a') as usize;
57
58 if inside {
59 let index = 26 * second + first;
61 bab[index] = version;
62 positive |= aba[index] == version;
63 } else {
64 let index = 26 * first + second;
65 aba[index] = version;
66 positive |= bab[index] == version;
67 }
68 }
69 } else if w[1] == b'[' {
70 inside = true;
71 } else if w[1] == b']' {
72 inside = false;
73 } else {
74 if positive {
76 count += 1;
77 }
78 version += 1;
79 positive = false;
80 }
81 }
82
83 if positive { count + 1 } else { count }
84}