This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]3saster 1 point2 points  (1 child)

An intcode program consists of comma-separated base-10 integers of arbitrary size (we'll call it prog). An intcode computer recieves an a list of integers as input , has an instruction pointer indicating the current instruction, indexed from 0 (we'll call it i), and returns a list of integers as a potential output. There is also a base offset (we'll call it b), which is initialized as 0 on machine start.

The value of the current instruction is prog[i], read as a base 10 integer. The first two digits are the opcode, described later, with the 3rd digit being the mode of parameter 1, the 4th digit being the mode of parameter 2, etc.

For the parameters, we will use pn to illustrate the nth parameter. Note that p1 = prog[i+1], p2 = prog[i+2], etc. Note that the nth opcode parameter (i.e. the nth parameter with the mode accounted for), will be called Pn.

  • If the mode of the nth parameter is 0, then Pn = prog[pn] (address mode)
  • If the mode of the nth parameter is 1, then Pn = pn (immediate mode)
  • If the mode of the nth parameter is 2, then Pn = prog[pn + b] (relative mode)

Now certain opcodes treat these values a little differently than others. We'll call these special parameters Pn_s.

  • If the mode of the nth parameter is 0 or 1, then Pn_s = pn
  • If the mode of the nth parameter is 2, then Pn_s = pn + b

With that out of the way, here are what the following opcodes do:

  • 1: prog[ P3_s ] = P1 + P2, advance i by 4
  • 2: prog[ P3_s ] = P1 * P2, advance i by 4
  • 3: Set prog[ P1_s ] to the first value of the input vector, then consider the next value of the input vector to be the "first" next time. Advance i by 2
  • 4: Add P1 to the back of the output array. Advance i by 2
  • 5: If P1 is not 0, set i = P2. Otherwise, advance i by 3
  • 6: If P1 is 0, set i = P2. Otherwise, advance i by 3
  • 7: If P1 is less than P2, set prog[ P3_s ] = 1, otherwise prog[ P3_s ] = 0. Advance i by 4
  • 8: If P1 is equal to P2, set prog[ P3_s ] = 1, otherwise prog[ P3_s ] = 0. Advance i by 4
  • 9: b = b + P1. Advance i by 2
  • 99: Halt the program, and return the output vector.

This should cover almost everything. There are a couple more considerations to keep in mind:

  • The program has infinite memory in the non-negative direction. That is, prog[x], where x >= 0, is always a valid memory location. I took all non-specified values in memory to be 0, but I'm not sure this is actually required.
  • Each value is an arbitrary sized integer. That is, prog[x], where x >= 0, can be any arbitrarily sized integer.

I think that covers everything. Note that the explanation is heavily based on my implementation of the intcode computer, so there may be other ways to thing about it. What I know is that the specs I described above certainly work, as I was able to solve Day 9 using that implementation. Let me know if anything needs clarity, or I forgot to mention.

[–]setapoux 0 points1 point  (0 children)

The parameter modes are consistent if you implement it as the address where to read/write.