diff --git a/src/holt59/aoc/2024/day17.py b/src/holt59/aoc/2024/day17.py index 5806513..02cb697 100644 --- a/src/holt59/aoc/2024/day17.py +++ b/src/holt59/aoc/2024/day17.py @@ -101,17 +101,17 @@ class Solver(BaseSolver): yield ",".join(map(str, run(registers.copy(), program))) - # out_index = next(i for i in range(0, len(program), 2) if program[i] == 5) - # out_register = "ABC"[program[out_index + 1] - 4] - - # there is only one jump instruction and it goes back to the beginning of the - # program + # last instruction is JNZ 0 (jump at the beginning), and it is the only jump + # in the program jnz_indices = [i for i in range(0, len(program), 2) if program[i] == 3] - assert ( - len(jnz_indices) == 1 - and jnz_indices[0] == len(program) - 2 - and program[-1] == 0 - ) + assert jnz_indices == [len(program) - 2] and program[-1] == 0 + + # previous instruction is dividing A by 8, or A = A >> 3 + assert program[-4:-2] == [0, 3] + + # previous instruction is a OUT B % 8, and it is the only OUT in the program + out_indices = [i for i in range(0, len(program), 2) if program[i] == 5] + assert out_indices == [len(program) - 6] and program[len(program) - 5] == 5 valid: list[int] = [0] for p in reversed(program): @@ -119,10 +119,10 @@ class Solver(BaseSolver): for v in valid: a_high = v << 3 for a_low in range(0, 2**3): - a = a_high | a_low - b = (((a % 8) ^ 7) ^ (a >> ((a % 8) ^ 7))) ^ 4 - if b % 8 == p: - new_valid.append(a) + registers["A"] = a_high | a_low + run(registers, program[:-6]) + if registers["B"] % 8 == p: + new_valid.append(a_high | a_low) valid = new_valid assert run(registers | {"A": min(valid)}, program) == program