Day 7, Year 2015: Some Assembly Required
First read the problem description.
import networkx as nx
import matplotlib.pyplot as plt
= 'Input'
INPUT
def value(wires, token):
try:
= int(token)
value except ValueError:
= wires.get(token, 0)
value
return value
= 0xffff
mask
def compute(wires, tokens):
if len(tokens) == 1:
return value(wires, tokens[0])
if tokens[0] == 'NOT':
return mask - value(wires, tokens[1])
if tokens[1] == 'AND':
return value(wires, tokens[0]) & value(wires, tokens[2])
if tokens[1] == 'OR':
return value(wires, tokens[0]) | value(wires, tokens[2])
if tokens[1] == 'LSHIFT':
return (value(wires, tokens[0]) << value(wires, tokens[2])) & mask
if tokens[1] == 'RSHIFT':
return value(wires, tokens[0]) >> value(wires, tokens[2])
assert False
def run(wires, s):
if not s:
return
= s.split()
tokens -1]] = compute(wires, tokens[:-2])
wires[tokens[
def add_to_graph(dg, s):
if not s:
return
= s.split()
tokens = None
input1 = None
input2 = tokens[-1]
output = tokens[:-2]
tokens if len(tokens) == 1:
if tokens[0].isdigit():
= INPUT
input1 else:
= tokens[0]
input1 elif tokens[0] == 'NOT':
if tokens[1].isdigit():
= INPUT
input1 else:
= tokens[1]
input1 else:
= tokens[0]
input1 = tokens[2]
input2
if input1 and not input1.isdigit():
= s)
dg.add_edge(output, input1, code if input2 and not input2.isdigit():
= s)
dg.add_edge(output, input2, code
def run_graph(wires, dg):
= reversed(list(nx.topological_sort(nx.line_graph(dg))))
nodes for (fn, tn) in nodes:
'code', '')) run(wires, dg[fn][tn].get(
= {}
wires = """123 -> x
instructions 456 -> y
x AND y -> d
x OR y -> e
x LSHIFT 2 -> f
y RSHIFT 2 -> g
NOT x -> h
NOT y -> i"""
= nx.DiGraph()
dg for s in instructions.splitlines():
add_to_graph(dg, s)
run_graph(wires, dg)assert value(wires, 'd') == 72
assert value(wires, 'e') == 507
assert value(wires, 'f') == 492
assert value(wires, 'g') == 114
assert value(wires, 'h') == 65412
assert value(wires, 'i') == 65079
assert value(wires, 'x') == 123
assert value(wires, 'y') == 456
import import_ipynb
import helper
= helper.read_file('2015_7.txt') s
= {}
wires = nx.DiGraph()
dg for instr in s.splitlines():
add_to_graph(dg, instr)
run_graph(wires, dg)print(wires['a'])
= {'b': wires['a']}
wires
dg.remove_node(INPUT)
run_graph(wires, dg)print(wires['a'])
956
40149
Source code of the solution(s):