#!/usr/bin/env python3 import sys input_file = sys.argv[1] with open(input_file) as fd: lines = [line.rstrip() for line in fd.readlines()] vec = tuple[int, int] pos: vec box = list() moves: list[vec] = list() directions = { "^": (-1, 0), # ^ ">": (0, 1), # > "v": (1, 0), # v "<": (0, -1), # < } sub = { "#": "##", "O": "[]", ".": "..", "@": "@.", } boxing = True for i, line in enumerate(lines): if not line: boxing = False elif boxing: bline = list() for char in line: bline += list(sub[char]) if "@" in bline: j = bline.index("@") pos = i, j # bline[j] = "." box.append(bline) else: for c in line: direction = directions[c] moves.append(direction) def print_box() -> None: for bline in box: print("".join(bline)) print() print_box() for move in moves: def do(i: int, j: int) -> None | set[vec]: ii, jj = i + move[0], j + move[1] char = box[ii][jj] moving = {(i, j)} if char == "#": return None elif char == ".": return moving else: r = do(ii, jj) if r is None: return None moving |= r if char == "[": npos = (ii, jj + 1) if npos not in moving: r = do(npos[0], npos[1]) if r is None: return None moving |= r elif char == "]": npos = (ii, jj - 1) if npos not in moving: r = do(npos[0], npos[1]) if r is None: return None moving |= r return moving moving = do(pos[0], pos[1]) if moving is None: continue olc: list[str] = list() for i, j in moving: olc.append(box[i][j]) box[i][j] = "." print(82, moving) print(83, olc) for i, j in moving: ii, jj = i + move[0], j + move[1] box[ii][jj] = olc.pop(0) # box[pos[0]][pos[1]] = "." pos = pos[0] + move[0], pos[1] + move[1] print(move, pos) # print_box() score = 0 for i, bline in enumerate(box): for j, char in enumerate(bline): if char == "[": score += 100 * i + j print(score)