summaryrefslogtreecommitdiffstats
path: root/2020/day8/gamechild.py
blob: 3763c785c6a2d44fcc99912b8d68b71bdc5afdbe (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
boot_code = list()


def gameon(acc, cx, sf):
    """emulates the game until a loop or the end"""

    while cx not in sf:
        sf.add(cx)

        if cx == len(boot_code):
            print(acc)
            exit(0)

        if boot_code[cx][0] == "acc":
            acc += boot_code[cx][1]
        elif boot_code[cx][0] == "jmp":
            cx += boot_code[cx][1] - 1
        else:  # nop
            pass

        cx += 1


with open("input", "r") as file:
    for line in file:
        line = line.strip()
        oparg = line.split(" ")
        boot_code.append((oparg[0], int(oparg[1])))


cursor = 0
accumulator = 0
sofar = set()

# we are allowed to keep a 'main' branch and keep jmp/nops separate because
# task calls for only one instruction change over the whole code

while cursor not in sofar:
    sofar.add(cursor)

    if boot_code[cursor][0] == "acc":
        accumulator += boot_code[cursor][1]
    elif boot_code[cursor][0] == "jmp":
        # one for the jmp
        gameon(accumulator, cursor + boot_code[cursor][1], sofar.copy())
        # one for the nop
        gameon(accumulator, cursor + 1, sofar.copy())
        cursor += boot_code[cursor][1] - 1
    elif boot_code[cursor][0] == "nop":
        # one for the nop
        gameon(accumulator, cursor + 1, sofar.copy())
        # one for the jmp
        gameon(accumulator, cursor + boot_code[cursor][1], sofar.copy())

    cursor += 1