advent-of-code/2024/17/two_fixed.py
2024-12-25 12:59:49 +01:00

79 lines
2.2 KiB
Python

#!/usr/bin/env python3
import sys
input_file = sys.argv[1]
with open(input_file) as fd:
lines = [line.rstrip() for line in fd.readlines()]
original_B = int(lines[1].split(":")[1])
original_C = int(lines[2].split(":")[1])
program = [int(p) for p in lines[4].split(":")[1].split(",")]
def output_given_A(A: int) -> list[int]:
instruction_pointer = 0
B = original_B
C = original_C
output: list[int] = list()
while instruction_pointer in range(len(program)):
instruction = program[instruction_pointer]
literal_operator = program[instruction_pointer + 1]
if instruction == 1:
B = B ^ literal_operator
elif instruction == 3:
if A != 0:
instruction_pointer = literal_operator
continue
elif instruction == 4:
B = B ^ C
else:
combined_operator = literal_operator
if literal_operator == 4:
combined_operator = A
elif literal_operator == 5:
combined_operator = B
elif literal_operator == 6:
combined_operator = C
if instruction == 2:
B = combined_operator % 8
elif instruction == 5:
output.append(combined_operator % 8)
else:
trunc_div = A >> combined_operator
if instruction == 0:
A = trunc_div
elif instruction == 6:
B = trunc_div
else:
C = trunc_div
instruction_pointer += 2
return output
def input_to_a(input_numbers: list[int]) -> int:
A = 0
for number in reversed(input_numbers):
A = (A << 3) + number
return A
input_numbers: list[int] = program.copy()
output_numbers: list[int] = output_given_A(input_to_a(input_numbers))
while output_numbers != program:
for i in reversed(range(len(input_numbers))):
attempted_number = 0
while len(output_numbers) != len(program) or output_numbers[i] != program[i]:
input_numbers[i] = attempted_number
A = input_to_a(input_numbers)
output_numbers = output_given_A(A)
attempted_number += 1
print(A)