Skip to content

Commit b932101

Browse files
committed
Year 2017 Day 4
1 parent d80e555 commit b932101

File tree

8 files changed

+616
-1
lines changed

8 files changed

+616
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ pie
244244
| 1 | [Inverse Captcha](https://adventofcode.com/2017/day/1) | [Source](src/year2017/day01.rs) | 1 |
245245
| 2 | [Corruption Checksum](https://adventofcode.com/2017/day/2) | [Source](src/year2017/day02.rs) | 3 |
246246
| 3 | [Spiral Memory](https://adventofcode.com/2017/day/3) | [Source](src/year2017/day03.rs) | 2 |
247+
| 4 | [High-Entropy Passphrases](https://adventofcode.com/2017/day/4) | [Source](src/year2017/day04.rs) | 94 |
247248

248249
## 2016
249250

benches/benchmark.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ mod year2017 {
9595
benchmark!(year2017, day01);
9696
benchmark!(year2017, day02);
9797
benchmark!(year2017, day03);
98+
benchmark!(year2017, day04);
9899
}
99100

100101
mod year2019 {

input/year2017/day04.txt

Lines changed: 512 additions & 0 deletions
Large diffs are not rendered by default.

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ pub mod year2017 {
223223
pub mod day01;
224224
pub mod day02;
225225
pub mod day03;
226+
pub mod day04;
226227
}
227228

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

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ fn year2016() -> Vec<Solution> {
141141
}
142142

143143
fn year2017() -> Vec<Solution> {
144-
vec![solution!(year2017, day01), solution!(year2017, day02), solution!(year2017, day03)]
144+
vec![
145+
solution!(year2017, day01),
146+
solution!(year2017, day02),
147+
solution!(year2017, day03),
148+
solution!(year2017, day04),
149+
]
145150
}
146151

147152
fn year2019() -> Vec<Solution> {

src/year2017/day04.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! # High-Entropy Passphrases
2+
//!
3+
//! ## Part One
4+
//!
5+
//! We use a [`FastSet`] to detect duplicates. Sorting the words in each line
6+
//! then checking for duplicates in adjacent values also works but is slower.
7+
//!
8+
//! ## Part Two
9+
//!
10+
//! To detect anagrams we first convert each word into a histogram of its letter frequency values.
11+
//! As the cardinality is at most 26 we can use a fixed size array to represent the set.
12+
//!
13+
//! Then a [`FastSet`] is used to detect duplicates. Sorting the letters in each word so that
14+
//! anagrams become the same also works but is slower.
15+
use crate::util::hash::*;
16+
17+
type Input<'a> = Vec<&'a str>;
18+
19+
pub fn parse(input: &str) -> Input<'_> {
20+
input.lines().collect()
21+
}
22+
23+
pub fn part1(input: &Input<'_>) -> u32 {
24+
let mut result = 0;
25+
let mut seen = FastSet::new();
26+
27+
for line in input {
28+
result += 1;
29+
30+
for token in line.split_ascii_whitespace() {
31+
// Insert returns `false` if the value is already in the set.
32+
if !seen.insert(token.as_bytes()) {
33+
result -= 1;
34+
break;
35+
}
36+
}
37+
38+
seen.clear();
39+
}
40+
41+
result
42+
}
43+
44+
pub fn part2(input: &Input<'_>) -> u32 {
45+
let mut result = 0;
46+
let mut seen = FastSet::new();
47+
48+
for line in input {
49+
result += 1;
50+
51+
for token in line.split_ascii_whitespace() {
52+
// Calculate the frequency of each letter, as anagrams will have the same values.
53+
let mut freq = [0_u8; 26];
54+
55+
for b in token.bytes() {
56+
freq[(b - b'a') as usize] += 1;
57+
}
58+
59+
if !seen.insert(freq) {
60+
result -= 1;
61+
break;
62+
}
63+
}
64+
65+
seen.clear();
66+
}
67+
68+
result
69+
}

tests/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ mod year2017 {
8888
mod day01_test;
8989
mod day02_test;
9090
mod day03_test;
91+
mod day04_test;
9192
}
9293

9394
mod year2019 {

tests/year2017/day04_test.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use aoc::year2017::day04::*;
2+
3+
const FIRST_EXAMPLE: &str = "\
4+
aa bb cc dd ee
5+
aa bb cc dd aa
6+
aa bb cc dd aaa";
7+
8+
const SECOND_EXAMPLE: &str = "\
9+
abcde fghij
10+
abcde xyz ecdab
11+
a ab abc abd abf abj
12+
iiii oiii ooii oooi oooo
13+
oiii ioii iioi iiio";
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)