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))
|