Coverage for src\aoc2022\days\day5.py: 100%
47 statements
« prev ^ index » next coverage.py v7.0.0, created at 2022-12-23 05:19 +0000
« prev ^ index » next coverage.py v7.0.0, created at 2022-12-23 05:19 +0000
1from typing import List, Tuple
3from src.aoc2022 import utils
5stacks_type = Tuple[List[str], ...]
6moves_type = List[Tuple[int, int, int]]
9def parse_data(raw_data: str) -> Tuple[stacks_type, moves_type]:
10 """
11 Parses the raw text input into the initial configuration and the move list
13 :param raw_data: Raw text data to be parsed
14 :type raw_data: str
16 :return: Initial Configuration and move list
17 :rtype: List[Tuple[int]]
18 """
19 configuration_data, move_data = raw_data.split("\n\n")
21 stack_rows = configuration_data.split("\n")
22 reversed_rows = stack_rows[::-1]
23 num_stacks = int(reversed_rows[0].split(" ")[-2])
25 stacks: Tuple[List[str], ...] = tuple([] for _ in range(num_stacks))
27 for row in reversed_rows[1:]:
28 values = row[1::4]
29 for idx, value in enumerate(values):
30 if value != " ":
31 stacks[idx].append(value)
33 moves = []
34 move_lines = move_data.split("\n")
35 for move_line in move_lines:
36 split_move = move_line.split(" ")
37 num_transfer = int(split_move[1])
38 start_stack = int(split_move[3])
39 end_stack = int(split_move[5])
41 moves.append((num_transfer, start_stack, end_stack))
43 return stacks, moves
46def transfer_items(stacks: stacks_type, moves: moves_type) -> str:
47 """
48 Computes the final state of the stacks after applying the moves
50 :param stacks: Tuple of lists representing each stack
51 :type stacks: Tuple[List[str]]
53 :param moves: List of tuples for each move
54 :type moves: List[Tuple[int]]
56 :return: value at the top of each stack after moves
57 :rtype: str
58 """
60 for n, start, stop in moves:
61 for _ in range(n):
62 v = stacks[start - 1].pop()
63 stacks[stop - 1].append(v)
65 top_boxes = []
66 for s in stacks:
67 if len(s) > 0:
68 top_boxes.append(s[-1])
69 else:
70 top_boxes.append(" ")
72 return "".join(top_boxes)
75def transfer_multiple_items(stacks: stacks_type, moves: moves_type) -> str:
76 """
77 Computes the final state of the stacks after applying the moves
78 moving multiple boxes in a single move
80 :param stacks: Tuple of lists representing each stack
81 :type stacks: Tuple[List[str]]
83 :param moves: List of tuples for each move
84 :type moves: List[Tuple[int]]
86 :return: value at the top of each stack after moves
87 :rtype: str
88 """
90 for n, start, stop in moves:
92 v = stacks[start - 1][-n:]
93 for _ in range(n):
94 stacks[start - 1].pop()
95 stacks[stop - 1].extend(v)
97 top_boxes = []
98 for s in stacks:
99 if len(s) > 0:
100 top_boxes.append(s[-1])
101 else:
102 top_boxes.append(" ")
104 return "".join(top_boxes)
107if __name__ == "__main__": # pragma: no cover
108 data = utils.get_raw_data("./src/aoc2022/data/day5.txt")
109 stacks, moves = parse_data(data)
110 result = transfer_items(stacks, moves)
111 print(f"The final state of the stacks is {result}")
113 stacks, moves = parse_data(data)
114 result = transfer_multiple_items(stacks, moves)
115 print(f"The final state of the stacks is {result}")