|
| 1 | +import re |
| 2 | +import typing as t |
| 3 | +from dataclasses import dataclass |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | + |
| 7 | +@dataclass |
| 8 | +class State: |
| 9 | + name: str |
| 10 | + action_if_0: tuple[t.Literal[0, 1], t.Literal[1, -1], str] |
| 11 | + action_if_1: tuple[t.Literal[0, 1], t.Literal[1, -1], str] |
| 12 | + |
| 13 | + |
| 14 | +with Path(Path(__file__).parent, "input").open() as f: |
| 15 | + instructions = [line.rstrip("\n") for line in f] |
| 16 | + |
| 17 | +begin_state = instructions[0][-2] |
| 18 | +steps_stop = int(re.search(r"\d+", instructions[1]).group(0)) # type: ignore |
| 19 | +states: dict[str, State] = {} |
| 20 | +tape: list[t.Literal[0, 1]] = [0] |
| 21 | +cursor = 0 |
| 22 | + |
| 23 | + |
| 24 | +def move_cursor(tape: list[t.Literal[0, 1]], cursor: int) -> int: |
| 25 | + if cursor == -1: |
| 26 | + tape.insert(0, 0) |
| 27 | + return 0 |
| 28 | + elif cursor == len(tape): |
| 29 | + tape.append(0) |
| 30 | + return cursor |
| 31 | + |
| 32 | + |
| 33 | +for i in range(3, len(instructions), 10): |
| 34 | + state_name = instructions[i][-2] |
| 35 | + action_if_0 = ( |
| 36 | + int(instructions[i + 2][-2]), |
| 37 | + -1 |
| 38 | + if instructions[i + 3].removeprefix(" - Move one slot to the ")[:-1] |
| 39 | + == "left" |
| 40 | + else 1, |
| 41 | + instructions[i + 4][-2], |
| 42 | + ) |
| 43 | + action_if_1 = ( |
| 44 | + int(instructions[i + 6][-2]), |
| 45 | + -1 |
| 46 | + if instructions[i + 7].removeprefix(" - Move one slot to the ")[:-1] |
| 47 | + == "left" |
| 48 | + else 1, |
| 49 | + instructions[i + 8][-2], |
| 50 | + ) |
| 51 | + states[state_name] = State(state_name, action_if_0, action_if_1) # type: ignore |
| 52 | + |
| 53 | +current_state = states[begin_state] |
| 54 | + |
| 55 | +for _ in range(steps_stop): |
| 56 | + action = ( |
| 57 | + current_state.action_if_0 if tape[cursor] == 0 else current_state.action_if_1 |
| 58 | + ) |
| 59 | + |
| 60 | + tape[cursor] = action[0] |
| 61 | + cursor = move_cursor(tape, cursor + action[1]) |
| 62 | + current_state = states[action[2]] |
| 63 | + |
| 64 | +print(f"Result: {sum(tape)}") |
0 commit comments