79 lines
2.2 KiB
Python
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)
|