Skip to content

Commit 7b78f45

Browse files
committed
Year 2017 Day 17
1 parent 215e46d commit 7b78f45

File tree

7 files changed

+72
-0
lines changed

7 files changed

+72
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
252252
| 14 | [Disk Defragmentation](https://adventofcode.com/2017/day/14) | [Source](src/year2017/day14.rs) | 422 |
253253
| 15 | [Dueling Generators](https://adventofcode.com/2017/day/15) | [Source](src/year2017/day15.rs) | 425000 |
254254
| 16 | [Permutation Promenade](https://adventofcode.com/2017/day/16) | [Source](src/year2017/day16.rs) | 66 |
255+
| 17 | [Spinlock](https://adventofcode.com/2017/day/17) | [Source](src/year2017/day17.rs) | 84 |
255256

256257
## 2016
257258

benches/benchmark.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ mod year2017 {
117117
benchmark!(year2017, day14);
118118
benchmark!(year2017, day15);
119119
benchmark!(year2017, day16);
120+
benchmark!(year2017, day17);
120121
}
121122

122123
mod year2019 {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub mod year2017 {
9999
pub mod day14;
100100
pub mod day15;
101101
pub mod day16;
102+
pub mod day17;
102103
}
103104

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

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ fn year2017() -> Vec<Solution> {
164164
solution!(year2017, day14),
165165
solution!(year2017, day15),
166166
solution!(year2017, day16),
167+
solution!(year2017, day17),
167168
]
168169
}
169170

src/year2017/day17.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! # Spinlock
2+
//!
3+
//! There are two insights that speed up part two.
4+
//!
5+
//! The first is that we don't need a buffer. We only need to preserve the last value inserted
6+
//! whenever the index becomes zero. Once 50 million values have been inserted then this value
7+
//! is the final result.
8+
//!
9+
//! The second trick is realizing that we can insert multiple values at a time before the index
10+
//! wraps around. For example if the index is 1, the current value 10,000 and the step 300,
11+
//! then we can insert 34 values at once. The [`div_ceil`] method is perfect for this computation.
12+
//!
13+
//! This reduces the number of loops needed to approximately √50000000 = 7071.
14+
//!
15+
//! [`div_ceil`]: usize::div_ceil
16+
use crate::util::parse::*;
17+
18+
pub fn parse(input: &str) -> usize {
19+
input.unsigned()
20+
}
21+
22+
pub fn part1(input: &usize) -> u16 {
23+
let step = input + 1;
24+
let mut index = 0;
25+
let mut buffer = vec![0];
26+
27+
for n in 0..2017 {
28+
index = (index + step) % buffer.len();
29+
buffer.insert(index, n + 1);
30+
}
31+
32+
buffer[(index + 1) % buffer.len()]
33+
}
34+
35+
pub fn part2(input: &usize) -> usize {
36+
let step = input + 1;
37+
let mut n: usize = 1;
38+
let mut index = 0;
39+
let mut result = 0;
40+
41+
while n <= 50_000_000 {
42+
if index == 0 {
43+
result = n;
44+
}
45+
46+
let skip = (n - index).div_ceil(step);
47+
n += skip;
48+
index = (index + skip * step) % n;
49+
}
50+
51+
result
52+
}

tests/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ mod year2017 {
101101
mod day14_test;
102102
mod day15_test;
103103
mod day16_test;
104+
mod day17_test;
104105
}
105106

106107
mod year2019 {

tests/year2017/day17_test.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use aoc::year2017::day17::*;
2+
3+
const EXAMPLE: &str = "3";
4+
5+
#[test]
6+
fn part1_test() {
7+
let input = parse(EXAMPLE);
8+
assert_eq!(part1(&input), 638);
9+
}
10+
11+
#[test]
12+
fn part2_test() {
13+
let input = parse(EXAMPLE);
14+
assert_eq!(part2(&input), 1222153);
15+
}

0 commit comments

Comments
 (0)