Luke 10 AoC, quick'n'dirty:
SPOILER ALERT! Vis spoiler
Kode
import re
from collections import defaultdict
class Bot(object):
def __init__(self, botid):
self.botid = botid
self.high = None
self.low = None
def ok(self):
return (self.high != None) and (self.low != None)
def add(self, num):
if (self.high and self.low) or (num in (self.high, self.low)):
return
elif self.high:
if num > self.high:
self.low = self.high
self.high = num
else:
self.low = num
elif self.low:
if num < self.low:
self.high = self.low
self.low = num
else:
self.high = num
else:
self.high = num
bots = {}
outputs = {}
instructions = open("10.txt").readlines()
for i in xrange(len(instructions)):
for inst in instructions:
m0 = re.match("value (\d*) goes to bot (\d*)", inst)
m1 = re.match("bot (\d*) gives low to (bot|output) (\d*) and high to (bot|output) (\d*)", inst)
if m0:
val, bot = map(int, m0.groups())
if bot not in bots:
bots[bot] = Bot(bot)
bots[bot].add(val)
if m1:
src_bot, dst_lo, dst_hi = map(int, [m1.group(1), m1.group(3), m1.group(5)])
dst_lo_type, dst_hi_type = m1.group(2), m1.group(4)
if (src_bot in bots) and bots[src_bot].ok():
if dst_lo_type == 'bot':
if dst_lo not in bots:
bots[dst_lo] = Bot(dst_lo)
bots[dst_lo].add(bots[src_bot].low)
else:
outputs[dst_lo] = bots[src_bot].low
if dst_hi_type == 'bot':
if dst_hi not in bots:
bots[dst_hi] = Bot(dst_hi)
bots[dst_hi].add(bots[src_bot].high)
else:
outputs[dst_hi] = bots[src_bot].high
for bot in bots:
if bots[bot].high == 61 and bots[bot].low == 17:
print "Part 1: %d" % bots[bot].botid
print "Part 2: %d" % (outputs[0]*outputs[1]*outputs[2])
Logikken var å bare gå gjennom hver instruksjon N^2 ganger, og forkaste en om den ikke ga mening enda. En optimalisering kunne ha vært å fjerne en instruksjon etter at all informasjonen i den er oppbrukt, men worst-case ville fortsatt vært N^2.
Den beste løsningen ville vært å bygge et avhengighetskart, og så regnet seg bakover til den riktige dronen, men inputfilen var såpass kort her at jeg tok meg friheten til å ta en snarvei.