advent-of-code/2024/15/two.py
2024-12-25 12:59:49 +01:00

111 lines
2.4 KiB
Python

#!/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)