2018 Day 19 Complete!
This commit is contained in:
parent
ba9d79b98f
commit
184e9d7639
137
2018/day19/problem
Normal file
137
2018/day19/problem
Normal file
@ -0,0 +1,137 @@
|
||||
Advent of Code
|
||||
|
||||
--- Day 19: Go With The Flow ---
|
||||
|
||||
With the Elves well on their way constructing the North Pole base, you turn
|
||||
your attention back to understanding the inner workings of programming the
|
||||
device.
|
||||
|
||||
You can't help but notice that the device's opcodes don't contain any flow
|
||||
control like jump instructions. The device's manual goes on to explain:
|
||||
|
||||
"In programs where flow control is required, the instruction pointer can be
|
||||
bound to a register so that it can be manipulated directly. This way,
|
||||
setr/seti can function as absolute jumps, addr/addi can function as relative
|
||||
jumps, and other opcodes can cause truly fascinating effects."
|
||||
|
||||
This mechanism is achieved through a declaration like #ip 1, which would
|
||||
modify register 1 so that accesses to it let the program indirectly access the
|
||||
instruction pointer itself. To compensate for this kind of binding, there are
|
||||
now six registers (numbered 0 through 5); the five not bound to the
|
||||
instruction pointer behave as normal. Otherwise, the same rules apply as the
|
||||
last time you worked with this device.
|
||||
|
||||
When the instruction pointer is bound to a register, its value is written to
|
||||
that register just before each instruction is executed, and the value of that
|
||||
register is written back to the instruction pointer immediately after each
|
||||
instruction finishes execution. Afterward, move to the next instruction by
|
||||
adding one to the instruction pointer, even if the value in the instruction
|
||||
pointer was just updated by an instruction. (Because of this, instructions
|
||||
must effectively set the instruction pointer to the instruction before the one
|
||||
they want executed next.)
|
||||
|
||||
The instruction pointer is 0 during the first instruction, 1 during the
|
||||
second, and so on. If the instruction pointer ever causes the device to
|
||||
attempt to load an instruction outside the instructions defined in the
|
||||
program, the program instead immediately halts. The instruction pointer starts
|
||||
at 0.
|
||||
|
||||
It turns out that this new information is already proving useful: the CPU in
|
||||
the device is not very powerful, and a background process is occupying most of
|
||||
its time. You dump the background process' declarations and instructions to a
|
||||
file (your puzzle input), making sure to use the names of the opcodes rather
|
||||
than the numbers.
|
||||
|
||||
For example, suppose you have the following program:
|
||||
|
||||
#ip 0
|
||||
seti 5 0 1
|
||||
seti 6 0 2
|
||||
addi 0 1 0
|
||||
addr 1 2 3
|
||||
setr 1 0 0
|
||||
seti 8 0 4
|
||||
seti 9 0 5
|
||||
|
||||
When executed, the following instructions are executed. Each line contains the
|
||||
value of the instruction pointer at the time the instruction started, the
|
||||
values of the six registers before executing the instructions (in square
|
||||
brackets), the instruction itself, and the values of the six registers after
|
||||
executing the instruction (also in square brackets).
|
||||
|
||||
ip=0 [0, 0, 0, 0, 0, 0] seti 5 0 1 [0, 5, 0, 0, 0, 0]
|
||||
ip=1 [1, 5, 0, 0, 0, 0] seti 6 0 2 [1, 5, 6, 0, 0, 0]
|
||||
ip=2 [2, 5, 6, 0, 0, 0] addi 0 1 0 [3, 5, 6, 0, 0, 0]
|
||||
ip=4 [4, 5, 6, 0, 0, 0] setr 1 0 0 [5, 5, 6, 0, 0, 0]
|
||||
ip=6 [6, 5, 6, 0, 0, 0] seti 9 0 5 [6, 5, 6, 0, 0, 9]
|
||||
|
||||
In detail, when running this program, the following events occur:
|
||||
|
||||
• The first line (#ip 0) indicates that the instruction pointer should be
|
||||
bound to register 0 in this program. This is not an instruction, and so
|
||||
the value of the instruction pointer does not change during the processing
|
||||
of this line.
|
||||
• The instruction pointer contains 0, and so the first instruction is
|
||||
executed (seti 5 0 1). It updates register 0 to the current instruction
|
||||
pointer value (0), sets register 1 to 5, sets the instruction pointer to
|
||||
the value of register 0 (which has no effect, as the instruction did not
|
||||
modify register 0), and then adds one to the instruction pointer.
|
||||
• The instruction pointer contains 1, and so the second instruction, seti 6
|
||||
0 2, is executed. This is very similar to the instruction before it: 6 is
|
||||
stored in register 2, and the instruction pointer is left with the value
|
||||
2.
|
||||
• The instruction pointer is 2, which points at the instruction addi 0 1 0.
|
||||
This is like a relative jump: the value of the instruction pointer, 2, is
|
||||
loaded into register 0. Then, addi finds the result of adding the value in
|
||||
register 0 and the value 1, storing the result, 3, back in register 0.
|
||||
Register 0 is then copied back to the instruction pointer, which will
|
||||
cause it to end up 1 larger than it would have otherwise and skip the next
|
||||
instruction (addr 1 2 3) entirely. Finally, 1 is added to the instruction
|
||||
pointer.
|
||||
• The instruction pointer is 4, so the instruction setr 1 0 0 is run. This
|
||||
is like an absolute jump: it copies the value contained in register 1, 5,
|
||||
into register 0, which causes it to end up in the instruction pointer. The
|
||||
instruction pointer is then incremented, leaving it at 6.
|
||||
• The instruction pointer is 6, so the instruction seti 9 0 5 stores 9 into
|
||||
register 5. The instruction pointer is incremented, causing it to point
|
||||
outside the program, and so the program ends.
|
||||
|
||||
What value is left in register 0 when the background process halts?
|
||||
|
||||
Your puzzle answer was 888.
|
||||
|
||||
--- Part Two ---
|
||||
|
||||
A new background process immediately spins up in its place. It appears
|
||||
identical, but on closer inspection, you notice that this time, register 0
|
||||
started with the value 1.
|
||||
|
||||
What value is left in register 0 when this new background process halts?
|
||||
|
||||
Your puzzle answer was 10708992.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
|
||||
References
|
||||
|
||||
Visible links
|
||||
. https://adventofcode.com/
|
||||
. https://adventofcode.com/2018/about
|
||||
. https://adventofcode.com/2018/events
|
||||
. https://adventofcode.com/2018/settings
|
||||
. https://adventofcode.com/2018/auth/logout
|
||||
. Advent of Code Supporter
|
||||
https://adventofcode.com/2018/support
|
||||
. https://adventofcode.com/2018
|
||||
. https://adventofcode.com/2018
|
||||
. https://adventofcode.com/2018/support
|
||||
. https://adventofcode.com/2018/sponsors
|
||||
. https://adventofcode.com/2018/leaderboard
|
||||
. https://adventofcode.com/2018/stats
|
||||
. https://adventofcode.com/2018/sponsors
|
||||
. https://adventofcode.com/2018/day/16
|
||||
. https://adventofcode.com/2018/day/16
|
||||
. https://en.wikipedia.org/wiki/Program_counter
|
||||
. https://adventofcode.com/2018/day/16
|
||||
. https://adventofcode.com/2018
|
||||
. https://adventofcode.com/2018/day/19/input
|
Loading…
Reference in New Issue
Block a user