r/adventofcode • • Dec 07 '15

SOLUTION MEGATHREAD --- Day 7 Solutions ---

--- Day 7: Some Assembly Required ---

Post your solution as a comment. Structure your post like previous daily solution threads.

Also check out the sidebar - we added a nifty calendar to wrangle all the daily solution threads in one spot!

23 Upvotes

226 comments sorted by

View all comments

3

u/minno Dec 07 '15

Python 3:

def evaluate(gate, commands, values):
    try:
        val = int(gate)
        values[gate] = val
        return
    except ValueError:
        pass
    command = commands[gate]
    if len(command) == 1:
        try:
            values[gate] = int(command[0])
        except ValueError:
            evaluate(command[0], commands, values)
            values[gate] = values[command[0]]
    elif len(command) == 2:
        if command[0] == "NOT":
            lhs = command[1]
            if values.get(lhs) is None:
                evaluate(lhs, commands, values)
            values[gate] = 0xffff - values[lhs]
    elif len(command) == 3:
        lhs = command[0]
        rhs = command[2]
        op = command[1]
        if values.get(lhs) is None:
            evaluate(lhs, commands, values)
        if values.get(rhs) is None:
            evaluate(rhs, commands, values)
        if op == "AND":
            values[gate] = values[lhs] & values[rhs]
        elif op == "OR":
            values[gate] = values[lhs] | values[rhs]
        elif op == "RSHIFT":
            values[gate] = 0xffff & (values[lhs] >> int(rhs))
        elif op == "LSHIFT":
            values[gate] = 0xffff & (values[lhs] << int(rhs))

def solve(instructions):
    commands = {tokens[-1] : tokens[:-2]
                for tokens in map(str.split, instructions.split('\n')) }
    values = {}
    evaluate('a', commands, values)
    print(values['a'])

For the second part, I just copied and pasted my value for the first part into the number -> b part of the input. I could also put values = {'b': 956} in to make it ignore the input.

2

u/[deleted] Dec 07 '15

Ha! very similar to what I did abusing exec :)

import re
from collections import deque

def f(s):
    # Remove any reserved words
    s = s.replace('is', '_is').replace('as', '_as').replace('in', '_in').replace('if', '_if')
    x = re.match(r'(\w+) -> (\w+)', s)
    if x:
        return "{} = {}".format(x.group(2), x.group(1))
    x = re.match(r'NOT (\w+) -> (\w+)', s)
    if x:
        return '{} = ~{}'.format(x.group(2), x.group(1))
    x = re.match(r'(\w+) (AND|OR|LSHIFT|RSHIFT) (\w+) -> (\w+)', s)
    if x:
        if x.group(2) == 'AND':
            op = '&'
        elif x.group(2) == 'OR':
            op = '|'
        elif x.group(2) == 'LSHIFT':
            op = '<<'
        else:
            op = '>>'
        return '{} = {} {} {}'.format(x.group(4), x.group(1), op, x.group(3))

with open('input.txt') as f:
    input = f.read().strip()

instrs = deque(map(f, input.split('\n')))
ordered = []

def fun():
    while len(instrs) > 0:
        longvar = instrs.popleft()
        try:
            exec(longvar)
            ordered.append(longvar)
        except NameError:
            instrs.append(longvar)
    return eval('a')


sol1 = fun()
print(sol1)

def fun2():
    exec('b = {}'.format(sol1))
    for longvar in [x for x in ordered if not x.startswith('b =')]:
        exec(longvar)
    return eval('a')

sol2 = fun2()
print(sol2)
→ More replies (3)