Created
December 30, 2017 05:09
-
-
Save randrews/307ead1d987799e295b92afd07c2c4e2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
class Bot: | |
def __init__(self, group, low, high): | |
self._queue = [] | |
self._low_target = low | |
self._high_target = high | |
self._group = group | |
def give(self, value): | |
self._queue.append(value) | |
def ready(self): | |
return len(self._queue) >= 2 | |
def run(self): | |
a, b = self.shift() | |
if a > b: a, b = b, a | |
self._group.send(self._low_target, a) | |
self._group.send(self._high_target, b) | |
def shift(self): | |
item_a, item_b = self._queue[:2] | |
self._queue = self._queue[2:] | |
return [item_a, item_b] | |
def peek(self): | |
return self._queue[:2] | |
class BotGroup: | |
def __init__(self): | |
self._bots = {} | |
self._outputs = {} | |
self._part1 = None | |
def send(self, target, value): | |
if target[1] == 'bot': | |
self._bots[target[0]].give(value) | |
elif target[1] == 'output': | |
self._outputs[target[0]] = value | |
def create(self, id, low, high): | |
if not id in self._bots: self._bots[id] = Bot(self, low, high) | |
def load_file(self, filename): | |
bot_re = re.compile(r'bot (\d+) gives low to (bot|output) (\d+) and high to (bot|output) (\d+)') | |
give_re = re.compile(r'value (\d+) goes to bot (\d+)') | |
gives = [] | |
with open(filename) as f: | |
for line in f: | |
bmatch = bot_re.match(line) | |
gmatch = give_re.match(line) | |
if bmatch: | |
print(line) | |
self.create(int(bmatch[1]), (int(bmatch[3]), bmatch[2]), (int(bmatch[5]), bmatch[4])) | |
elif gmatch: | |
gives.append((int(gmatch[2]), int(gmatch[1]))) | |
for give in gives: | |
print(give) | |
self._bots[give[0]].give(give[1]) | |
def run_part1(self): | |
while True: | |
any_ready = False | |
for id, bot in self._bots.items(): | |
if bot.ready(): | |
any_ready = True | |
a, b = bot.peek() | |
if (a == 61 and b == 17) or (a == 17 and b == 61): | |
self._part1 = self._part1 or id | |
bot.run() | |
if not any_ready: break | |
def part1(self): | |
return self._part1 | |
def part2(self): | |
return self._outputs[0] * self._outputs[1] * self._outputs[2] | |
bg = BotGroup() | |
bg.load_file('day10.txt') | |
bg.run_part1() | |
print('Part 1: %d' % bg.part1()) | |
print('Part 2: %d' % bg.part2()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment