import re from string import ascii_lowercase, ascii_uppercase EXAMPLE = """ [D] [N] [C] [Z] [M] [P] 1 2 3 1 5 9 move 1 from 2 to 1 move 3 from 1 to 3 move 2 from 2 to 1 move 1 from 1 to 2 """ def clean(text: str) -> list[str]: return list(filter(lambda l: l.strip() != "", text.splitlines())) def solve(lines: list[str]): s = 0 stacks = [[] for _ in range(10)] for (_, line) in enumerate(lines): if line.startswith("move"): continue for (j, c) in enumerate(line): if c in ascii_uppercase: i = (j - 1) // 4 stacks[i].append(c) for stack in stacks: stack.reverse() r = re.compile(r"move (\d+) from (\d+) to (\d+)") for line in lines: if not line.startswith("move"): continue if (m := r.match(line)): amount, fr, to = m.groups() amount = int(amount) fr = int(fr) - 1 to = int(to) - 1 stacks[to] += reversed(stacks[fr][-amount:]) stacks[fr] = stacks[fr][:-amount] m = "" for s in stacks: if s: m += s[-1] # 10:34 return m def solve2(lines: list[str]): s = 0 stacks = [[] for _ in range(10)] for (_, line) in enumerate(lines): if line.startswith("move"): continue for (j, c) in enumerate(line): if c in ascii_uppercase: i = (j - 1) // 4 stacks[i].append(c) for stack in stacks: stack.reverse() r = re.compile(r"move (\d+) from (\d+) to (\d+)") for line in lines: if not line.startswith("move"): continue if (m := r.match(line)): amount, fr, to = m.groups() amount = int(amount) fr = int(fr) - 1 to = int(to) - 1 stacks[to] += stacks[fr][-amount:] stacks[fr] = stacks[fr][:-amount] m = "" for s in stacks: if s: m += s[-1] # 11:56 return m def main(): example = clean(EXAMPLE) print("Example 1:", solve(example)) data = clean(open("i5.txt").read()) print("Solution 1:", solve(data)) example = clean(EXAMPLE) print("Example 2:", solve2(example)) data = clean(open("i5.txt").read()) print("Solution 2:", solve2(data)) if __name__ == "__main__": main()