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