Coprocessor Conflagration
Tags: adventofcode, algorithms, computerscience, programming
Published: 2022-07-19 18:08:51

## [Advent of Code 2017 Day 23](https://adventofcode.com/2017/day/23)

## [Try the simulator to walk through your puzzle input](https://aoccoprocessorconflagration.rmion.repl.co/)
- I built a simulator
- It doesn't generate the correct answer for me for Part 2
- But it does show how a valid program runs

## Part 1
1. Solve for `X` where `X = `...
2. `mul` instruction?
3. Referring to Day 18 to ensure full understanding
4. Copy-paste-refactor
5. After troubleshooting clumsy mistakes, success!

### Solve for `X` where `X = `...
> the amount of times the mul instruction is invoked

### `mul` instruction?
- My input is a program containing instructions
- There are four types of instructions: `set`, `sub`, `mul` and `jnz`
- Each instruction works with two operands: a `register` and a `value`
- The pattern of each instruction resembles: `instruction X Y`
- The registers are one of 8 variables, labeled `a-h`
- All eight registers initially store the value `0`

Working through Advent of Code backwards seems to present me with an advantage here, since this feels very similar to all the `Intcode` puzzles from later years.

For that reason, I feel confident I'll be able to solve at least Part 1.

However, I sense I need to refer to Day 18's puzzle. The instructions mention it as the first encounter of this type of puzzle.

### Referring to Day 18 to ensure full understanding
- Flash forward: [I solved Part 1 for Day 18](https://dev.to/rmion/duet-31pp)
- The missing context was expected: the program runs until an address pointer refers outside of the bounds of the instruction list
- Good news: I wrote an algorithm that accounts for eight instructions...and can now just copy it, remove some instructions, and update where appropriate!

### Copy-paste-refactor
- I'll start by reusing my algorithm from Day 18 Part 1
- Then I'll remove several unused instructions
- And finally, adjust the jump instruction based on today's puzzle's definition

### After troubleshooting clumsy mistakes, success!
- My code from Day 18 Part 1 was missing some important possibilities that my code from Part 2 incorporated

Logic like:
- Accounting for strings or numbers as either `X` or `Y` operands
- The case where a key may not be in `registers` at the moment a `jnz` instruction runs
- There is no longer a case where an instruction could receive only one operand

Alas, after resolving these issues...

...my algorithm generated the correct answer!

## Part 2

1. Solve for `X` where `X = `...
2. What's so unique about `a` and `h`?
3. Running the program with `a` set to 1
4. Building a simulator to step through at my own pace

### Solve for `X` where `X = `...
> the value left in register `h` if the program were to run to completion after setting register `a` to `1`

### What's so unique about `a` and `h`?
- Both `a` and `h` are featured in only one instruction
- `a` is featured in a `jnz` instruction - which acts depending on whether `a` is a value other than `0`
- `h` is featured in a `sub` instruction - which subtracts some amount from the value stored in register `h`

### Running the program with `a` set to 1
Observations:
- Setting `a` to `1` initially causes the program to process four important instructions that set registers `b` thru `f`
- `b` becomes a six-digit positive integer
- `g` becomes nearly the same integer, but negative
- The program cycles through a subset of instructions until `g` climbs its way back up to `0`
- Only to be reset to that six-digit negative integer by way of a jump back a few instructions later
- `f` must be `0` for the program to avoid skipping the only line that adjusts `h`
- `g` must be `0` for the program to reach that `f` jump instruction
- But `g` will never be `0` as long as `b` causes `g` to reset to some non-0 number in the instruction prior to the jump

### Building a simulator to step through at my own pace
- I reused the code from my Day 18 Part 2 simulator
- After a lot of deletions, I had it setup to run Day 23 Part 2, with `a` starting as `1`

I quickly saw the parts that looped endlessly:
1. `jnz g -8`
2. `jnz g -13`

Due to this earlier instruction:
`sub b -100000`

And several instances of this instruction:
`set g b`

Both `jnz` instructions initialized loops that took hundreds of thousands of times to bring `g` to `0`.

However, I remain baffled.

### Why isn't the answer `1`?
The last few instructions of my puzzle input are as follows:
```
jnz g -13
jnz f 2
sub h -1
set g b
sub g c
jnz g 2
jnz 1 3
sub b -17
jnz 1 -23
```

- If `g` is `0`, it would jump to the next line
- If `f` is `0`, it would jump to the next line
- I see no other way to arrive at this instruction that subtracts `-1` from `h`
- Since no other line `set`s `h`, it must start at and be `0` when this instruction runs
- Causing it to store the value `1`
- Assuming the next two instructions run
- The next `jnz` would need to be skipped in order to arrive at the next instruction
- Because `jnz 1 3` seems like the only way to cause this program to halt

And once it halts, `h` would have the value `1`.

Sadly, that's not the correct answer.

So, as in Day 18 Part 2:
- I'm stumped

## Celebrating my accomplishments
- I solved Part 1!
- I built a simulator to see how the program runs...specifically to understand Part 2!

Bummers:
- I didn't understand what the instructions meant by `optimize the program`: did it mean to change the input?
- I was wrong about what I felt was the only possible value that `h` could store once the program terminated
- Thus, I did not solve Part 2

I sense that for Part 2 of Days 18 and 23 I am missing some hidden trick to make the program arrive at a particular instruction with the right value stored in a register.

Maybe Reddit's Solution Megathread can reveal the answer.