View Single Post
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.