-
Notifications
You must be signed in to change notification settings - Fork 0
/
day05.py
64 lines (48 loc) · 1.65 KB
/
day05.py
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
56
57
58
59
60
61
62
63
64
import copy
import re
from collections import deque
from dataclasses import dataclass
from .shared import Solution
@dataclass
class Move:
times: int
src: int
dest: int
def main(input_: list[str]) -> Solution:
split = input_.index("")
crates = input_[:split]
moves = input_[split + 1 :]
todo = parse_moves(moves)
stacks_1 = parse_stacks(crates)
stacks_2 = copy.deepcopy(stacks_1)
for t in todo:
apply_move_single(t, stacks_1)
apply_move_multi(t, stacks_2)
return Solution(
"".join([s[0] for s in stacks_1.values()]),
"".join([s[0] for s in stacks_2.values()]),
)
def parse_stacks(crates: list[str]) -> dict[int, deque]:
stack_numbers = [int(n) for n in re.findall(r"\d", crates.pop())]
stacks = {num: deque() for num in stack_numbers}
for line in crates:
for idx, i in enumerate(range(1, len(stacks.keys()) * 4, 4), start=1):
letter = line[i]
if letter == " ":
continue
stacks[idx].append(letter)
return stacks
def parse_moves(moves: list[str]) -> list[Move]:
todo = []
for line in moves:
todo.append(Move(*[int(m) for m in re.findall(r"\d+", line)]))
return todo
def apply_move_single(move: Move, stacks: dict[int, deque]):
for i in range(move.times):
stacks[move.dest].appendleft(stacks[move.src].popleft())
def apply_move_multi(move: Move, stacks: dict[int, deque]):
tmp = []
for i in range(move.times):
tmp.append(stacks[move.src].popleft())
tmp.reverse()
stacks[move.dest].extendleft(tmp)