summaryrefslogtreecommitdiffstats
path: root/23/solution.py
diff options
context:
space:
mode:
Diffstat (limited to '23/solution.py')
-rw-r--r--23/solution.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/23/solution.py b/23/solution.py
new file mode 100644
index 0000000..00144bf
--- /dev/null
+++ b/23/solution.py
@@ -0,0 +1,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))