Created
December 10, 2016 05:38
-
-
Save vedgar/229c2780fbd92a52f7065b42ef72c389 to your computer and use it in GitHub Desktop.
You _can_ write readable code and still get into top100 on Advent of code. :-)
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 collections | |
test = '''\ | |
value 5 goes to bot 2 | |
bot 2 gives low to bot 1 and high to bot 0 | |
value 3 goes to bot 1 | |
bot 1 gives low to output 1 and high to bot 0 | |
bot 0 gives low to output 2 and high to output 0 | |
value 2 goes to bot 2 | |
''' | |
input = open('d10_input.txt').read() | |
def parse(instructions): | |
for instruction in instructions.splitlines(): | |
first, *rest = instruction.split() | |
if first == 'value': | |
value, goes, to, bot, n = rest | |
yield first, int(value), int(n) | |
elif first == 'bot': | |
n, gives, low, to, what1, n1, and_, high, to, what2, n2 = rest | |
yield 'low', int(n), what1, int(n1) | |
yield 'high', int(n), what2, int(n2) | |
def prepare(instructions): | |
values, low, high = collections.defaultdict(list), {}, {} | |
for instruction_type, *rest in parse(instructions): | |
if instruction_type == 'value': | |
value, bot = rest | |
values[bot].append(value) | |
else: | |
from_, *destination = rest | |
vars()[instruction_type][from_] = destination | |
return values, low, high | |
def execute(instructions): | |
values, low, high = prepare(instructions) | |
outputs = {} | |
def give(destination, value): | |
destination_type, destination_index = destination | |
if destination_type == 'bot': | |
values[destination_index].append(value) | |
elif destination_type == 'output': | |
outputs[destination_index] = value | |
else: | |
assert False, 'cannot happen' | |
while True: | |
for bot, bot_values in values.items(): | |
assert len(bot_values) <= 2, 'too many values' | |
if len(bot_values) == 2: | |
if set(bot_values) == {61, 17}: | |
print(bot) | |
low_value, high_value = sorted(bot_values) | |
bot_values.clear() | |
give(low[bot], low_value) | |
give(high[bot], high_value) | |
break | |
else: break | |
assert not any(values for values in values.values()) | |
return outputs | |
assert execute(test) == dict(enumerate([5, 2, 3])) | |
outputs = execute(input) | |
print(outputs[0] * outputs[1] * outputs[2]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment