aoc-2018-python

Advent of Code 2018 Solutions in Python
git clone https://git.sinitax.com/sinitax/aoc-2018-python
Log | Files | Refs | README | sfeed.txt

part1 (5076B)


      1--- Day 19: Go With The Flow ---
      2
      3With the Elves well on their way constructing the North Pole base, you turn your attention back to
      4understanding the inner workings of programming the device.
      5
      6You can't help but notice that the device's opcodes don't contain any flow control like jump
      7instructions. The device's manual goes on to explain:
      8
      9"In programs where flow control is required, the instruction pointer can be bound to a register so
     10that it can be manipulated directly. This way, setr/seti can function as absolute jumps, addr/addi
     11can function as relative jumps, and other opcodes can cause truly fascinating effects."
     12
     13This mechanism is achieved through a declaration like #ip 1, which would modify register 1 so that
     14accesses to it let the program indirectly access the instruction pointer itself. To compensate for
     15this kind of binding, there are now six registers (numbered 0 through 5); the five not bound to the
     16instruction pointer behave as normal. Otherwise, the same rules apply as the last time you worked
     17with this device.
     18
     19When the instruction pointer is bound to a register, its value is written to that register just
     20before each instruction is executed, and the value of that register is written back to the
     21instruction pointer immediately after each instruction finishes execution. Afterward, move to the
     22next instruction by adding one to the instruction pointer, even if the value in the instruction
     23pointer was just updated by an instruction. (Because of this, instructions must effectively set the
     24instruction pointer to the instruction before the one they want executed next.)
     25
     26The instruction pointer is 0 during the first instruction, 1 during the second, and so on. If the
     27instruction pointer ever causes the device to attempt to load an instruction outside the
     28instructions defined in the program, the program instead immediately halts. The instruction pointer
     29starts at 0.
     30
     31It turns out that this new information is already proving useful: the CPU in the device is not very
     32powerful, and a background process is occupying most of its time.  You dump the background process'
     33declarations and instructions to a file (your puzzle input), making sure to use the names of the
     34opcodes rather than the numbers.
     35
     36For example, suppose you have the following program:
     37
     38#ip 0
     39seti 5 0 1
     40seti 6 0 2
     41addi 0 1 0
     42addr 1 2 3
     43setr 1 0 0
     44seti 8 0 4
     45seti 9 0 5
     46
     47When executed, the following instructions are executed. Each line contains the value of the
     48instruction pointer at the time the instruction started, the values of the six registers before
     49executing the instructions (in square brackets), the instruction itself, and the values of the six
     50registers after executing the instruction (also in square brackets).
     51
     52ip=0 [0, 0, 0, 0, 0, 0] seti 5 0 1 [0, 5, 0, 0, 0, 0]
     53ip=1 [1, 5, 0, 0, 0, 0] seti 6 0 2 [1, 5, 6, 0, 0, 0]
     54ip=2 [2, 5, 6, 0, 0, 0] addi 0 1 0 [3, 5, 6, 0, 0, 0]
     55ip=4 [4, 5, 6, 0, 0, 0] setr 1 0 0 [5, 5, 6, 0, 0, 0]
     56ip=6 [6, 5, 6, 0, 0, 0] seti 9 0 5 [6, 5, 6, 0, 0, 9]
     57
     58In detail, when running this program, the following events occur:
     59
     60
     61 - The first line (#ip 0) indicates that the instruction pointer should be bound to register 0 in
     62this program. This is not an instruction, and so the value of the instruction pointer does not
     63change during the processing of this line.
     64
     65 - The instruction pointer contains 0, and so the first instruction is executed (seti 5 0 1).  It
     66updates register 0 to the current instruction pointer value (0), sets register 1 to 5, sets the
     67instruction pointer to the value of register 0 (which has no effect, as the instruction did not
     68modify register 0), and then adds one to the instruction pointer.
     69
     70 - The instruction pointer contains 1, and so the second instruction, seti 6 0 2, is executed. This
     71is very similar to the instruction before it: 6 is stored in register 2, and the instruction pointer
     72is left with the value 2.
     73
     74 - The instruction pointer is 2, which points at the instruction addi 0 1 0.  This is like a
     75relative jump: the value of the instruction pointer, 2, is loaded into register 0. Then, addi finds
     76the result of adding the value in register 0 and the value 1, storing the result, 3, back in
     77register 0. Register 0 is then copied back to the instruction pointer, which will cause it to end up
     781 larger than it would have otherwise and skip the next instruction (addr 1 2 3) entirely. Finally,
     791 is added to the instruction pointer.
     80
     81 - The instruction pointer is 4, so the instruction setr 1 0 0 is run. This is like an
     82absolute jump: it copies the value contained in register 1, 5, into register 0, which causes it to
     83end up in the instruction pointer. The instruction pointer is then incremented, leaving it at 6.
     84
     85 - The instruction pointer is 6, so the instruction seti 9 0 5 stores 9 into register 5. The
     86instruction pointer is incremented, causing it to point outside the program, and so the program
     87ends.
     88
     89
     90What value is left in register 0 when the background process halts?
     91
     92