Skip to content

Commit a4a25b2

Browse files
committed
Solution for Day 17.
1 parent c4ad677 commit a4a25b2

File tree

2 files changed

+106
-1
lines changed

2 files changed

+106
-1
lines changed

instructions/Day17.txt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
--- Day 17: Spinlock ---
2+
3+
Suddenly, whirling in the distance, you notice what looks like a
4+
massive, pixelated hurricane: a deadly spinlock. This spinlock isn't
5+
just consuming computing power, but memory, too; vast, digital mountains
6+
are being ripped from the ground and consumed by the vortex.
7+
8+
If you don't move quickly, fixing that printer will be the least of your
9+
problems.
10+
11+
This spinlock's algorithm is simple but efficient, quickly consuming
12+
everything in its path. It starts with a circular buffer containing only
13+
the value 0, which it marks as the current position. It then steps
14+
forward through the circular buffer some number of steps (your puzzle
15+
input) before inserting the first new value, 1, after the value it
16+
stopped on. The inserted value becomes the current position. Then, it
17+
steps forward from there the same number of steps, and wherever it
18+
stops, inserts after it the second new value, 2, and uses that as the
19+
new current position again.
20+
21+
It repeats this process of stepping forward, inserting a new value, and
22+
using the location of the inserted value as the new current position a
23+
total of 2017 times, inserting 2017 as its final operation, and ending
24+
with a total of 2018 values (including 0) in the circular buffer.
25+
26+
For example, if the spinlock were to step 3 times per insert, the
27+
circular buffer would begin to evolve like this (using parentheses to
28+
mark the current position after each iteration of the algorithm):
29+
30+
(0), the initial state before any insertions.
31+
0 (1): the spinlock steps forward three times (0, 0, 0), and then
32+
inserts the first value, 1, after it. 1 becomes the current position.
33+
0 (2) 1: the spinlock steps forward three times (0, 1, 0), and then
34+
inserts the second value, 2, after it. 2 becomes the current position.
35+
0 2 (3) 1: the spinlock steps forward three times (1, 0, 2), and then
36+
inserts the third value, 3, after it. 3 becomes the current position.
37+
38+
And so on:
39+
40+
0 2 (4) 3 1
41+
0 (5) 2 4 3 1
42+
0 5 2 4 3 (6) 1
43+
0 5 (7) 2 4 3 6 1
44+
0 5 7 2 4 3 (8) 6 1
45+
0 (9) 5 7 2 4 3 8 6 1
46+
47+
Eventually, after 2017 insertions, the section of the circular buffer
48+
near the last insertion looks like this:
49+
50+
1512 1134 151 (2017) 638 1513 851
51+
Perhaps, if you can identify the value that will ultimately be after the
52+
last value written (2017), you can short-circuit the spinlock. In this
53+
example, that would be 638.
54+
55+
What is the value after 2017 in your completed circular buffer?
56+
57+
Your puzzle answer was 1914.
58+
59+
--- Part Two ---
60+
61+
The spinlock does not short-circuit. Instead, it gets more angry. At
62+
least, you assume that's what happened; it's spinning significantly
63+
faster than it was a moment ago.
64+
65+
You have good news and bad news.
66+
67+
The good news is that you have improved calculations for how to stop the
68+
spinlock. They indicate that you actually need to identify the value
69+
after 0 in the current state of the circular buffer.
70+
71+
The bad news is that while you were determining this, the spinlock has
72+
just finished inserting its fifty millionth value (50000000).
73+
74+
What is the value after 0 the moment 50000000 is inserted?
75+
76+
Your puzzle answer was 41797835.
77+
78+
Your puzzle input was 343.
79+

src/day17.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,35 @@
1+
#include <deque>
2+
13
#include "default_includes.hpp"
24
#include "solution.hpp"
35

46
template<>
57
void solve<Day17>(std::istream& ins, std::ostream& outs)
68
{
7-
if (!ins.good()) { outs << "Failed to open input file!" << std::endl; }
9+
NOT_USED(ins);
10+
11+
const auto steps{343}; // input
12+
auto pos{0};
13+
std::deque<int> buffer;
14+
buffer.emplace_back(0);
15+
16+
for (auto i{1}; i <= 2017; ++i)
17+
{
18+
pos = ((pos + steps) % buffer.size()) + 1;
19+
buffer.emplace((buffer.begin() + pos), i);
20+
}
21+
22+
outs << "(Part 1) Value after 2017 = " << buffer[pos + 1] << std::endl;
23+
24+
auto value{0};
25+
pos = 0;
26+
for (auto i{1}; i <= 50000000; ++i)
27+
{
28+
// 0 will remain at index 0, therefore we can just update the
29+
// value if insertion index is 1.
30+
if ((pos = ((pos + steps) % i) + 1) == 1) { value = i; }
31+
}
32+
33+
outs << "(Part 2) Value after 0 = " << value << std::endl;
834
}
935

0 commit comments

Comments
 (0)