Passed
Push — main ( 83fd9b...e71399 )
by Yohann
57s
created

main.parse_initial_state()   A

Complexity

Conditions 4

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 14
rs 9.85
c 0
b 0
f 0
cc 4
nop 1
1
import pathlib
2
import re
3
from typing import cast, List, Tuple
4
5
MOVE_REGEX = re.compile(r'^move (\d+) from (\d+) to (\d+)$')
6
7
8
def parse_initial_state(state_lines):
9
    stack_ids = list(map(int, state_lines.pop().split()))
10
    stacks = {i: [] for i in sorted(stack_ids)}
11
12
    def split_x(chunk_size):
13
        return [line[i:i + chunk_size] for i in range(0, len(line), chunk_size + 1)]
14
15
    for line in reversed(state_lines):
16
        for create, stack in zip(split_x(3), stack_ids):
17
            if create == '   ':
18
                continue
19
20
            stacks[stack].append(create)
21
    return stacks
22
23
24
def parse_moves(lines) -> List[Tuple[int, int, int]]:
25
    return cast(
26
        List[Tuple[int, int, int]],
27
        [
28
            tuple(map(int, re.match(MOVE_REGEX, line).groups()))
29
            for line in lines
30
        ]
31
    )
32
33
34
def parse(lines):
35
    split_idx = lines.index('')
36
    return (
37
        parse_initial_state(lines[:split_idx]),
38
        parse_moves(lines[split_idx + 1:])
39
    )
40
41
42
def solve(init_state, moves, pick_group):
43
    state = {k: v[:] for k, v in init_state.items()}
44
45
    for n, from_, to in moves:
46
        pick = [state[from_].pop() for _ in range(n)]
47
        if pick_group:
48
            pick.reverse()
49
50
        state[to].extend(pick)
51
    return state
52
53
54
def collect_output(state):
55
    return ''.join(g[-1][1] for g in state.values())
56
57
58
def main():
59
    content = pathlib.Path('./input.txt').read_text()
60
    initial_state, moves = parse(content.splitlines())
61
62
    print("Part 1:", collect_output(solve(initial_state, moves, False)))
63
    print("Part 2:", collect_output(solve(initial_state, moves, True)))
64
65
66
if __name__ == '__main__':
67
    main()
68