summaryrefslogtreecommitdiffstats
path: root/23/solution.py
blob: 00144bfbfde70d9ac20c712a66077358eb46c99f (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
def run(instructions, a=0, b=0):
    ip = 0
    regs = {
        'a': a,
        'b': b,
    }

    def set(r, v):
        regs[r] = v
        return 1

    act = {
        'hlf': lambda r: set(r, regs[r] // 2),
        'tpl': lambda r: set(r, regs[r] * 3),
        'inc': lambda r: set(r, regs[r] + 1),
        'jmp': lambda offset: offset,
        'jie': lambda r, offset: offset if regs[r] % 2 == 0 else 1,
        'jio': lambda r, offset: offset if regs[r] == 1 else 1,
    }

    while 0 <= ip < len(instructions):
        ins, ops = instructions[ip]
        ip += act[ins](*ops)
        # print(f'ins={ins}, ops={ops}, a={regs["a"]}, b={regs["b"]}, ip={ip}')

    return regs

def part1(instructions):
    return run(instructions)['b']

def part2(instructons):
    return run(instructions, 1)['b']

if __name__ == '__main__':
    with open('input') as f:
        instructions = list()
        for line in f:
            line = line.rstrip()
            opcode, operands = line.split(' ', maxsplit=1)
            def parse_operand(s: str) -> int | str:
                if s[0] == '+':
                    return int(s[1:])
                elif s[0] == '-':
                    return -int(s[1:])
                return s
            operands = tuple(parse_operand(op) for op in operands.split(', '))
            instructions.append((opcode, operands))
    print(part1(instructions))
    print(part2(instructions))