advent_of_code_2022/day5/main.py
2022-12-05 14:28:40 +01:00

86 lines
1.9 KiB
Python

from dataclasses import dataclass
from common.file import read_data
test_dataset = [
" [D] ",
"[N] [C] ",
"[Z] [M] [P]",
" 1 2 3 ",
"",
"move 1 from 2 to 1",
"move 3 from 1 to 3",
"move 2 from 2 to 1",
"move 1 from 1 to 2",
]
@dataclass(frozen=True)
class Move:
quantity: int
of: int
to: int
def process_data(data: list[str]) -> tuple[list[list[str]], list[Move]]:
rows = []
steps = []
for line in data:
if line == "" or line.strip()[0] == "1":
continue
if line[0] == "m":
steps.append(line)
else:
rows.append(line)
stacks = _build_stacks(rows)
instructions = _build_instructions(steps)
return stacks, instructions
def _build_stacks(rows: list[str]) -> list[list[str]]:
stacks = []
i = 0
while i < len(rows[0]):
stack = []
for row in rows:
crate = row[i + 1 : i + 2]
if crate.strip() != "":
stack.insert(0, crate)
i += 4
stacks.append(stack)
return stacks
def _build_instructions(instructions: list[str]) -> list[Move]:
moves = []
for step in instructions:
splits = step.split(" ")
qty = int(splits[1])
of = int(splits[3]) - 1
to = int(splits[5]) - 1
moves.append(Move(quantity=qty, of=of, to=to))
return moves
def find_top_crates(stacks: list[list[str]], instructions: list[Move]) -> str:
for step in instructions:
for _ in range(step.quantity):
stacks[step.to].append(stacks[step.of].pop())
return "".join(stack[-1] for stack in stacks)
def top_crates(data: list) -> str:
stacks, instructions = process_data(data)
return find_top_crates(stacks, instructions)
if __name__ == "__main__":
dataset = read_data()
res = top_crates(dataset)
assert res == "CMZ", f"{res} is not the right value"