#!/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)))