advent-of-code/2024/17/one.py
2024-12-25 12:59:49 +01:00

70 lines
1.7 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()]
# program 3 bits numbers
# registers A, B, C: any int
# instruction 3 bits, operand 3 bits
# literal operand, combo operand: 0-3 literal, 4-6: register A,B,C
# instruction pointer starts at 0
# 0 adv: truncated division, numerator = A, denominator 2**combo operand -> A
# 1 bxl: bitwise XOR, B ^ literal operand -> B
# 2 bst: combo operand % 8 -> B
# 3 jnz: { A = 0: nothing; A != 0: literal operand -> IP } # no increase there!
# 4 bxc: bitwise XOR, B ^ C -> B # operand ignored
# 5 out: combo operand % 8 -> output
# 6 bdv: truncated division, numerator = A, denominator 2**combo operand -> B
# 7 cdv: truncated division, numerator = A, denominator 2**combo operand -> C
A = int(lines[0].split(":")[1])
B = int(lines[1].split(":")[1])
C = int(lines[2].split(":")[1])
program = [int(p) for p in lines[4].split(":")[1].split(",")]
output: list[int] = list()
ip = 0
while ip in range(len(program)):
inst = program[ip]
liop = program[ip + 1]
coop = liop
if liop == 4:
coop = A
elif liop == 5:
coop = B
elif liop == 6:
coop = C
trunc_div = A // 2**coop
if inst == 0:
A = trunc_div
elif inst == 1:
B = B ^ liop
elif inst == 2:
B = coop % 8
elif inst == 3:
if A != 0:
ip = liop
continue
elif inst == 4:
B = B ^ C
elif inst == 5:
output.append(coop % 8)
elif inst == 6:
B = trunc_div
elif inst == 7:
C = trunc_div
else:
raise NotImplementedError()
ip += 2
print(",".join([str(o) for o in output]))