Spaces:
Running
Running
File size: 2,751 Bytes
a4da721 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
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() |