aoc/2015/day07.py

80 lines
2.2 KiB
Python

#!/usr/bin/env python3
from typing import TextIO
import itertools
circuit: dict[str, int] = {}
class Continue(Exception):
pass
def part1(instructions: TextIO) -> int:
ins: list[str] = []
# process all instructions into a list
for l in instructions:
ins.append(l.strip())
# repeat until the list is empty
while len(ins) != 0:
for connection in ins:
cpart = connection.split()
# print(cpart, sep="")
cpart.remove("->")
# Exclude the destination
try:
# possibles = list(itertools.filterfalse(str.isupper, cpart))[:-1]
for p in range(len(cpart) - 1):
if not cpart[p].isnumeric() and not cpart[p].isupper():
if cpart[p] in circuit:
# Get the value?
# This error can be ignored, lol
cpart[p] = circuit[cpart[p]]
else:
# We can't do anything for this
raise Continue
except Continue:
continue
# assignment
if len(cpart) == 2:
circuit[cpart[1]] = int(cpart[0])
elif "NOT" in cpart:
circuit[cpart[-1]] = (
~int(cpart[1]) & 0xFFFF
) # see notes for why you can't just use ~
elif "AND" in cpart:
circuit[cpart[-1]] = int(cpart[0]) & int(cpart[2])
elif "OR" in cpart:
circuit[cpart[-1]] = int(cpart[0]) | int(cpart[2])
elif "LSHIFT" in cpart:
circuit[cpart[-1]] = int(cpart[0]) << int(cpart[2])
elif "RSHIFT" in cpart:
circuit[cpart[-1]] = int(cpart[0]) >> int(cpart[2])
ins.remove(connection)
# print(circuit)
return circuit["a"]
def part2(f: TextIO):
circuit["b"] = circuit["a"]
for k in list(circuit.keys()):
if k != "b":
del circuit[k]
return part1(f)
if __name__ == "__main__":
with open("day07.txt", "r") as f:
print(part1(f))
with open("day07.txt", "r") as f:
print(part2(f))