#!/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))