81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
|
#!/usr/bin/env python
|
||
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||
|
|
||
|
# Author: Sebastian Mark
|
||
|
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||
|
|
||
|
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||
|
|
||
|
|
||
|
def readinput():
|
||
|
with open("input", "r", encoding="utf-8") as file:
|
||
|
lines = file.readlines()
|
||
|
|
||
|
register = {}
|
||
|
register["A"] = int(lines[0].split(":")[1].strip())
|
||
|
register["B"] = int(lines[1].split(":")[1].strip())
|
||
|
register["C"] = int(lines[2].split(":")[1].strip())
|
||
|
|
||
|
program = list(map(int, lines[4].strip().split(":")[1].split(",")))
|
||
|
|
||
|
return register, program
|
||
|
|
||
|
|
||
|
def get_combo(register: dict, operant: int) -> int:
|
||
|
match operant:
|
||
|
case 0 | 1 | 2 | 3:
|
||
|
return operant
|
||
|
case 4:
|
||
|
return register["A"]
|
||
|
case 5:
|
||
|
return register["B"]
|
||
|
case 6:
|
||
|
return register["C"]
|
||
|
|
||
|
|
||
|
def run_programm(register: dict, program: list) -> list:
|
||
|
pointer = 0
|
||
|
output = []
|
||
|
while pointer < len(program):
|
||
|
opcode, operant = program[pointer], program[pointer + 1]
|
||
|
match opcode:
|
||
|
case 0: # adv
|
||
|
combo = get_combo(register, operant)
|
||
|
register["A"] //= 2**combo
|
||
|
case 1: # bxl
|
||
|
register["B"] ^= operant
|
||
|
case 2: # bst
|
||
|
combo = get_combo(register, operant)
|
||
|
register["B"] = combo % 8
|
||
|
case 3: # jnz
|
||
|
if register["A"] != 0:
|
||
|
pointer = operant
|
||
|
continue
|
||
|
case 4: # bxc
|
||
|
register["B"] ^= register["C"]
|
||
|
case 5: # out
|
||
|
combo = get_combo(register, operant)
|
||
|
output.append(combo % 8)
|
||
|
case 6: # bdv
|
||
|
combo = get_combo(register, operant)
|
||
|
register["B"] = register["A"] // (2**combo)
|
||
|
case 7: # cdv
|
||
|
combo = get_combo(register, operant)
|
||
|
register["C"] = register["A"] // (2**combo)
|
||
|
|
||
|
pointer += 2
|
||
|
|
||
|
return output
|
||
|
|
||
|
|
||
|
def main():
|
||
|
register, program = readinput()
|
||
|
|
||
|
# part 1
|
||
|
output = run_programm(register, program)
|
||
|
print("Program output: %s" % ",".join(map(str, output)))
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|