Spaces:
Running
Running
| def parse_input(file): | |
| with open(file, 'r') as f: | |
| lines = f.read().strip().split('\n') | |
| # Parse register values | |
| registers = {} | |
| for line in lines[:3]: | |
| reg, val = line.split(': ') | |
| registers[reg[-1]] = int(val) | |
| # Parse program | |
| program = [int(x) for x in lines[-1].split(',')] | |
| return registers, program | |
| class Computer: | |
| def __init__(self, registers, program): | |
| self.registers = registers.copy() | |
| self.program = program | |
| self.ip = 0 | |
| self.output = [] | |
| def get_combo_value(self, operand): | |
| if operand <= 3: | |
| return operand | |
| elif operand <= 6: | |
| return self.registers[chr(ord('A') + operand - 4)] | |
| return None # operand 7 is reserved | |
| def run(self): | |
| while self.ip < len(self.program): | |
| opcode = self.program[self.ip] | |
| operand = self.program[self.ip + 1] | |
| if opcode == 0: # adv | |
| power = self.get_combo_value(operand) | |
| self.registers['A'] //= (2 ** power) | |
| elif opcode == 1: # bxl | |
| self.registers['B'] ^= operand | |
| elif opcode == 2: # bst | |
| self.registers['B'] = self.get_combo_value(operand) % 8 | |
| elif opcode == 3: # jnz | |
| if self.registers['A'] != 0: | |
| self.ip = operand | |
| continue | |
| elif opcode == 4: # bxc | |
| self.registers['B'] ^= self.registers['C'] | |
| elif opcode == 5: # out | |
| value = self.get_combo_value(operand) % 8 | |
| self.output.append(str(value)) | |
| elif opcode == 6: # bdv | |
| power = self.get_combo_value(operand) | |
| self.registers['B'] = self.registers['A'] // (2 ** power) | |
| elif opcode == 7: # cdv | |
| power = self.get_combo_value(operand) | |
| self.registers['C'] = self.registers['A'] // (2 ** power) | |
| self.ip += 2 | |
| return ','.join(self.output) | |
| def solve_part1(registers, program): | |
| computer = Computer(registers, program) | |
| return computer.run() | |
| def solve_part2(registers, program): | |
| target = ','.join(str(x) for x in program) | |
| a = 1 | |
| while True: | |
| test_registers = registers.copy() | |
| test_registers['A'] = a | |
| computer = Computer(test_registers, program) | |
| output = computer.run() | |
| if output == target: | |
| return str(a) | |
| a += 1 | |
| def main(): | |
| registers, program = parse_input("./input.txt") | |
| # Part 1 | |
| print(solve_part1(registers, program)) | |
| # Part 2 | |
| print(solve_part2(registers, program)) | |
| if __name__ == "__main__": | |
| main() |