## Day 7, Year 2015: Some Assembly Required

import networkx as nx
import matplotlib.pyplot as plt

INPUT = 'Input'

def value(wires, token):
try:
value = int(token)
except ValueError:
value = wires.get(token, 0)

return value

def compute(wires, tokens):
if len(tokens) == 1:
return value(wires, tokens[0])
if tokens[0] == 'NOT':
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
tokens = s.split()
wires[tokens[-1]] = compute(wires, tokens[:-2])

if not s:
return
tokens = s.split()
input1 = None
input2 = None
output = tokens[-1]
tokens = tokens[:-2]
if len(tokens) == 1:
if tokens[0].isdigit():
input1 = INPUT
else:
input1 = tokens[0]
elif tokens[0] == 'NOT':
if tokens[1].isdigit():
input1 = INPUT
else:
input1 = tokens[1]
else:
input1 = tokens[0]
input2 = tokens[2]

if input1 and not input1.isdigit():
if input2 and not input2.isdigit():

def run_graph(wires, dg):
nodes = reversed(list(nx.topological_sort(nx.line_graph(dg))))
for (fn, tn) in nodes:
run(wires, dg[fn][tn].get('code', ''))
wires = {}
instructions = """123 -> x
456 -> y
x AND y -> d
x OR y -> e
x LSHIFT 2 -> f
y RSHIFT 2 -> g
NOT x -> h
NOT y -> i"""
dg = nx.DiGraph()
for s in instructions.splitlines():
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
s = helper.read_file('2015_7.txt')
wires = {}
dg = nx.DiGraph()
for instr in s.splitlines():
print(wires['a'])
956
40149