84 lines
2.3 KiB
Python
84 lines
2.3 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
|
|
|
|
|
|
def dig(depth: int, input_numbers: list[int]) -> int | None:
|
|
input_numbers = input_numbers.copy()
|
|
depth += 1
|
|
for i in range(8):
|
|
input_numbers[-depth] = i
|
|
A = input_to_a(input_numbers)
|
|
output_numbers = output_given_A(A)
|
|
if output_numbers[-depth:] == program[-depth:]:
|
|
if depth == len(program):
|
|
return A
|
|
res = dig(depth, input_numbers)
|
|
if res is not None:
|
|
return res
|
|
return None
|
|
|
|
|
|
print(dig(0, [0] * len(program)))
|