summaryrefslogtreecommitdiff
path: root/07/main.py
blob: 7babff9be09777edb61ee8f3f65e29ae74799dc5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/python



def eval_wire(wires, w):
    # Shortcut for cleaner code
    if w.isdigit():
        return int(w) & 65535

    result = 0
    tokens = wires[w]

    if len(tokens) == 1:
        result = eval_wire(wires, tokens[0])

    if len(tokens) == 2:
        if tokens[0] == "NOT":
            result = ~eval_wire(wires, tokens[1])

    if len(tokens) == 3:
        if tokens[1] == "AND":
            result = eval_wire(wires, tokens[0]) & eval_wire(wires, tokens[2])
        if tokens[1] == "OR":
            result = eval_wire(wires, tokens[0]) | eval_wire(wires, tokens[2])
        if tokens[1] == "LSHIFT":
            result = eval_wire(wires, tokens[0]) << eval_wire(wires, tokens[2])
        if tokens[1] == "RSHIFT":
            result = eval_wire(wires, tokens[0]) >> eval_wire(wires, tokens[2])

    result &= 65535
    wires[w] = [str(result)] # cache result
    return int(result)



def solve_partn(partn, lines):
    # Parse input into a marginally nicer form
    wires = {}
    for line in lines:
        words = line.split(" ")
        wires[words[-1]] = words[0 : -2]

    if partn == 2:
        wires["b"] = ["46065"]

    return eval_wire(wires, "a")



def main():
    # Read wire configuration from input text file
    with open("input.txt", "r") as f:
        lines = f.read().splitlines()

    print("Part 1 solution:", solve_partn(1, lines)) # 46065 for me
    print("Part 2 solution:", solve_partn(2, lines)) # 14134 for me



if __name__ == "__main__":
    main()