2015 day 7

This commit is contained in:
2026-06-01 19:13:04 +02:00
parent c2da074b7c
commit fc94052aac
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
import fileinput
def parse_circuit(inp):
instructions = {}
# dst: (OP, ARGS)
for line in inp:
op, dst = line.split(" -> ")
op = op.split(" ")
if len(op) == 1: # ASSIGN
src = op[0]
instructions[dst] = ("ASSIGN", src)
elif len(op) == 2: # NOT
assert op[0] == "NOT"
instructions[dst] = ("NOT", op[1])
elif len(op) == 3: # BINARY OP
instructions[dst] = (op[1], (op[0], op[2]))
return instructions
def main(inp):
instructions = parse_circuit(inp)
res = evaluate_instruction("a", instructions)
print("Part 1: ", res)
instructions["b"] = ("ASSIGN", str(res))
res = evaluate_instruction("a", instructions, state={}) # reset state
print("Part 2: ", res)
def evaluate_instruction(start_wire, instructions, state={}):
if start_wire in state:
return state[start_wire]
op, args = instructions[start_wire]
result = -1
if op == "ASSIGN":
if args.isdigit():
result = int(args)
else:
result = evaluate_instruction(args, instructions, state)
elif op == "NOT":
if args.isdigit():
result = 65535 - int(args)
else:
result = 65535 - evaluate_instruction(args, instructions, state)
elif op in ["AND", "OR", "LSHIFT", "RSHIFT"]:
left, right = args
if left.isdigit():
left = int(left)
else:
left = evaluate_instruction(left, instructions, state)
if right.isdigit():
right = int(right)
else:
right = evaluate_instruction(right, instructions, state)
match op:
case "OR":
result = left | right
case "AND":
result = left & right
case "LSHIFT":
result = left << right
case "RSHIFT":
result = left >> right
case _:
assert False, "Unreachable"
else:
assert False, "Unreachable"
state[start_wire] = result
return result
if __name__ == "__main__":
lines = [x.rstrip() for x in fileinput.input()]
main(lines)