125 lines
4.3 KiB
Python
125 lines
4.3 KiB
Python
|
#!/bin/python3
|
||
|
import sys,time,re
|
||
|
from pprint import pprint
|
||
|
sys.path.insert(0, '../../')
|
||
|
from fred import list2int,get_re,nprint,lprint,loadFile,dprint
|
||
|
start_time = time.time()
|
||
|
|
||
|
input_f = 'input'
|
||
|
|
||
|
def loadGates(input_f):
|
||
|
gates = {}
|
||
|
instructions = []
|
||
|
with open(input_f) as file:
|
||
|
for line in file:
|
||
|
if ':' in line:
|
||
|
tmp = line.split(': ')
|
||
|
gates[tmp[0]] = int(tmp[1])
|
||
|
if '->' in line:
|
||
|
tmp = line.replace('-> ','').rstrip().split(' ')
|
||
|
instructions.append(tmp)
|
||
|
return gates, instructions
|
||
|
|
||
|
#########################################
|
||
|
# #
|
||
|
# Part 1 #
|
||
|
# #
|
||
|
#########################################
|
||
|
def part1():
|
||
|
gates, instructions = loadGates(input_f)
|
||
|
|
||
|
#print(gates)
|
||
|
#print(instructions)
|
||
|
wait_for = []
|
||
|
for inst in instructions:
|
||
|
|
||
|
x,logic,y,z = inst
|
||
|
|
||
|
if x not in gates or y not in gates:
|
||
|
#print(inst)
|
||
|
wait_for.append(inst)
|
||
|
continue
|
||
|
|
||
|
for wdx, w in enumerate(wait_for):
|
||
|
x,logic,y,z = w
|
||
|
if x in gates and y in gates:
|
||
|
#print(wait_for,w,wdx)
|
||
|
# `AND` gates output `1` if *both* inputs are `1`; if either input is `0`, these gates output `0`.
|
||
|
if logic == 'AND':
|
||
|
gates[z] = 1 if gates[x] and gates[y] else 0
|
||
|
|
||
|
# `OR` gates output `1` if *one or both* inputs is `1`; if both inputs are `0`, these gates output `0`.
|
||
|
if logic == 'OR':
|
||
|
gates[z] = 1 if gates[x] or gates[y] else 0
|
||
|
|
||
|
# `XOR` gates output `1` if the inputs are *different*; if the inputs are the same, these gates output `0`.
|
||
|
if logic == 'XOR':
|
||
|
gates[z] = 1 if gates[x] != gates[y] else 0
|
||
|
wait_for.pop(wdx)
|
||
|
#input()
|
||
|
|
||
|
x,logic,y,z = inst
|
||
|
|
||
|
# `AND` gates output `1` if *both* inputs are `1`; if either input is `0`, these gates output `0`.
|
||
|
if logic == 'AND':
|
||
|
gates[z] = 1 if gates[x] and gates[y] else 0
|
||
|
|
||
|
# `OR` gates output `1` if *one or both* inputs is `1`; if both inputs are `0`, these gates output `0`.
|
||
|
if logic == 'OR':
|
||
|
gates[z] = 1 if gates[x] or gates[y] else 0
|
||
|
|
||
|
# `XOR` gates output `1` if the inputs are *different*; if the inputs are the same, these gates output `0`.
|
||
|
if logic == 'XOR':
|
||
|
gates[z] = 1 if gates[x] != gates[y] else 0
|
||
|
|
||
|
while len(wait_for) > 0:
|
||
|
for wdx, w in enumerate(wait_for):
|
||
|
x,logic,y,z = w
|
||
|
if x in gates and y in gates:
|
||
|
#print(wait_for,w,wdx)
|
||
|
# `AND` gates output `1` if *both* inputs are `1`; if either input is `0`, these gates output `0`.
|
||
|
if logic == 'AND':
|
||
|
gates[z] = 1 if gates[x] and gates[y] else 0
|
||
|
|
||
|
# `OR` gates output `1` if *one or both* inputs is `1`; if both inputs are `0`, these gates output `0`.
|
||
|
if logic == 'OR':
|
||
|
gates[z] = 1 if gates[x] or gates[y] else 0
|
||
|
|
||
|
# `XOR` gates output `1` if the inputs are *different*; if the inputs are the same, these gates output `0`.
|
||
|
if logic == 'XOR':
|
||
|
gates[z] = 1 if gates[x] != gates[y] else 0
|
||
|
wait_for.pop(wdx)
|
||
|
|
||
|
#dprint(gates)
|
||
|
result = ''
|
||
|
|
||
|
countZ = 0
|
||
|
|
||
|
for g in gates.keys():
|
||
|
if g[0] == 'z':
|
||
|
countZ += 1
|
||
|
|
||
|
for i in range(countZ-1,-1,-1):
|
||
|
#print(i)
|
||
|
#print(g,gates[g])
|
||
|
if i < 10:
|
||
|
result += str(gates['z0'+str(i)])
|
||
|
else:
|
||
|
result += str(gates['z'+str(i)])
|
||
|
print(result)
|
||
|
return int(result, 2)
|
||
|
|
||
|
start_time = time.time()
|
||
|
print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
||
|
|
||
|
|
||
|
#########################################
|
||
|
# #
|
||
|
# Part 2 #
|
||
|
# #
|
||
|
#########################################
|
||
|
def part2():
|
||
|
return
|
||
|
|
||
|
start_time = time.time()
|
||
|
print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|