summaryrefslogtreecommitdiffstats
path: root/day5/__init__.py
diff options
context:
space:
mode:
authorGravatar Tom van der Lee <t0m.vd.l33@gmail.com>2022-12-05 10:26:45 +0100
committerGravatar Tom van der Lee <t0m.vd.l33@gmail.com>2022-12-05 10:26:45 +0100
commit8b9919f784f93bdca7335354e7eea782b397fe0c (patch)
tree39100eada8e973faf4c5e7bf48f3e94b57f5c6e2 /day5/__init__.py
parent87f25f31adcc1a90bd99d40c5790290ecbcd7ce0 (diff)
download2022-8b9919f784f93bdca7335354e7eea782b397fe0c.tar.gz
2022-8b9919f784f93bdca7335354e7eea782b397fe0c.tar.bz2
2022-8b9919f784f93bdca7335354e7eea782b397fe0c.zip
Day 5
Diffstat (limited to 'day5/__init__.py')
-rw-r--r--day5/__init__.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/day5/__init__.py b/day5/__init__.py
new file mode 100644
index 0000000..a9aaba5
--- /dev/null
+++ b/day5/__init__.py
@@ -0,0 +1,108 @@
1# -*- coding: utf-8 -*-
2import re
3from abc import ABC
4from typing import Iterator, Any, TypedDict, Tuple, List
5from queue import LifoQueue
6
7from aoc import BaseAssignment
8
9move_regex = re.compile("^move (?P<amount>\d+) from (?P<start>\d+) to (?P<end>\d+)$")
10
11
12class Move(TypedDict):
13 amount: int
14 start: int
15 end: int
16
17
18class Assignment(BaseAssignment, ABC):
19 def parse_move(self, move: str) -> Move:
20 match = move_regex.match(move)
21 if match:
22 move = match.groupdict()
23 return Move(
24 amount=int(move["amount"]),
25 start=int(move["start"]),
26 end=int(move["end"]),
27 )
28
29 def parse_stacks(self, string_stacks: List[str]) -> List[LifoQueue]:
30 stacks = []
31 columns = string_stacks.pop().replace(" ", "")
32
33 for i in range(len(columns)):
34 stacks.append(LifoQueue())
35
36 for line in reversed(string_stacks):
37 for index, stack in enumerate(stacks):
38 item_index = (index * 4) + 1
39
40 try:
41 item = line[item_index]
42 if item != " ":
43 stack.put(item)
44 except IndexError:
45 pass
46
47 return stacks
48
49 def parse_input(self, input: Iterator) -> Tuple[List[LifoQueue], List[Move]]:
50 parsing_stacks = True
51 tmp_stacks = []
52 stacks = []
53 moves = []
54
55 for line in input:
56 if line == "":
57 parsing_stacks = False
58 stacks = self.parse_stacks(tmp_stacks)
59 continue
60
61 if parsing_stacks:
62 tmp_stacks.append(line)
63 else:
64 moves.append(self.parse_move(line))
65
66 return stacks, moves
67
68 def execute_moves(self, stacks: List[LifoQueue], moves: List[Move]):
69 raise NotImplementedError()
70
71 def run(self, input: Iterator) -> Any:
72 stacks, moves = self.parse_input(input)
73
74 self.execute_moves(stacks, moves)
75
76 return "".join([stack.get() for stack in stacks])
77
78
79class AssignmentOne(Assignment):
80 example_result = "CMZ"
81
82 def execute_moves(self, stacks: List[LifoQueue], moves: List[Move]):
83 for move in moves:
84 start = stacks[move["start"] - 1]
85 end = stacks[move["end"] - 1]
86
87 for _ in range(move["amount"]):
88 end.put(start.get())
89
90 return stacks
91
92
93class AssignmentTwo(Assignment):
94 example_result = "MCD"
95
96 def execute_moves(self, stacks: List[LifoQueue], moves: List[Move]):
97 for move in moves:
98 start = stacks[move["start"] - 1]
99 end = stacks[move["end"] - 1]
100
101 tmp_stack = LifoQueue()
102 for _ in range(move["amount"]):
103 tmp_stack.put(start.get())
104
105 while not tmp_stack.empty():
106 end.put(tmp_stack.get())
107
108 return stacks