Skip to content

Commit 7d5dd7f

Browse files
committed
Year 2016 Day 7
1 parent a1941a7 commit 7d5dd7f

File tree

8 files changed

+2122
-0
lines changed

8 files changed

+2122
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ pie
249249
| 4 | [Security Through Obscurity](https://adventofcode.com/2016/day/4) | [Source](src/year2016/day04.rs) | 75 |
250250
| 5 | [How About a Nice Game of Chess?](https://adventofcode.com/2016/day/5) | [Source](src/year2016/day05.rs) | 229000 |
251251
| 6 | [Signals and Noise](https://adventofcode.com/2016/day/6) | [Source](src/year2016/day06.rs) | 5 |
252+
| 7 | [Internet Protocol Version 7](https://adventofcode.com/2016/day/7) | [Source](src/year2016/day07.rs) | 354 |
252253

253254
## 2015
254255

benches/benchmark.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ mod year2016 {
7070
benchmark!(year2016, day04);
7171
benchmark!(year2016, day05);
7272
benchmark!(year2016, day06);
73+
benchmark!(year2016, day07);
7374
}
7475

7576
mod year2019 {

input/year2016/day07.txt

+2,000
Large diffs are not rendered by default.

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ pub mod year2016 {
195195
pub mod day04;
196196
pub mod day05;
197197
pub mod day06;
198+
pub mod day07;
198199
}
199200

200201
/// # Rescue Santa from deep space with a solar system adventure.

src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ fn all_solutions() -> Vec<Solution> {
108108
solution!(year2016, day04),
109109
solution!(year2016, day05),
110110
solution!(year2016, day06),
111+
solution!(year2016, day07),
111112
// 2019
112113
solution!(year2019, day01),
113114
solution!(year2019, day02),

src/year2016/day07.rs

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
}

tests/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ mod year2016 {
6363
mod day04_test;
6464
mod day05_test;
6565
mod day06_test;
66+
mod day07_test;
6667
}
6768

6869
mod year2019 {

tests/year2016/day07_test.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use aoc::year2016::day07::*;
2+
3+
const FIRST_EXAMPLE: &str = "\
4+
abba[mnop]qrst
5+
abcd[bddb]xyyx
6+
aaaa[qwer]tyui
7+
ioxxoj[asdfgh]zxcvbn";
8+
9+
const SECOND_EXAMPLE: &str = "\
10+
aba[bab]xyz
11+
xyx[xyx]xyx
12+
aaa[kek]eke
13+
zazbz[bzb]cdb";
14+
15+
#[test]
16+
fn part1_test() {
17+
let input = parse(FIRST_EXAMPLE);
18+
assert_eq!(part1(input), 2);
19+
}
20+
21+
#[test]
22+
fn part2_test() {
23+
let input = parse(SECOND_EXAMPLE);
24+
assert_eq!(part2(input), 3);
25+
}

0 commit comments

Comments
 (0)