|
| 1 | +//! # Internet Protocol Version 7 |
| 2 | +//! |
| 3 | +//! It's faster to treat the entire input as one big stream, using line breaks to increment |
| 4 | +//! the count if an address is valid. |
| 5 | +//! |
| 6 | +//! For part two there are at most 26 * 26 = 676 possible ABA or BAB sequences so we can use |
| 7 | +//! a fixed size array to keep track of which ones we've seen for the current address so far. |
| 8 | +pub fn parse(input: &str) -> &[u8] { |
| 9 | + input.as_bytes() |
| 10 | +} |
| 11 | + |
| 12 | +pub 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 | + // Next line |
| 33 | + if positive && !negative { |
| 34 | + count += 1; |
| 35 | + } |
| 36 | + positive = false; |
| 37 | + negative = false; |
| 38 | + } |
| 39 | + } |
| 40 | + |
| 41 | + if positive && !negative { |
| 42 | + count + 1 |
| 43 | + } else { |
| 44 | + count |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | +pub fn part2(input: &[u8]) -> usize { |
| 49 | + let mut count = 0; |
| 50 | + let mut version = 0; |
| 51 | + let mut inside = false; |
| 52 | + let mut positive = false; |
| 53 | + let mut aba = [usize::MAX; 676]; |
| 54 | + let mut bab = [usize::MAX; 676]; |
| 55 | + |
| 56 | + for w in input.windows(3) { |
| 57 | + if w[1].is_ascii_lowercase() { |
| 58 | + if w[0] == w[2] && w[0] != w[1] { |
| 59 | + let first = (w[0] - b'a') as usize; |
| 60 | + let second = (w[1] - b'a') as usize; |
| 61 | + |
| 62 | + if inside { |
| 63 | + // Reverse the order of letters |
| 64 | + let index = 26 * second + first; |
| 65 | + bab[index] = version; |
| 66 | + positive |= aba[index] == version; |
| 67 | + } else { |
| 68 | + let index = 26 * first + second; |
| 69 | + aba[index] = version; |
| 70 | + positive |= bab[index] == version; |
| 71 | + } |
| 72 | + } |
| 73 | + } else if w[1] == b'[' { |
| 74 | + inside = true; |
| 75 | + } else if w[1] == b']' { |
| 76 | + inside = false; |
| 77 | + } else { |
| 78 | + // Next line |
| 79 | + if positive { |
| 80 | + count += 1; |
| 81 | + } |
| 82 | + version += 1; |
| 83 | + positive = false; |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + if positive { |
| 88 | + count + 1 |
| 89 | + } else { |
| 90 | + count |
| 91 | + } |
| 92 | +} |
0 commit comments