2024-12-18 00:39:21 +01:00
|
|
|
from output import D, matrix
|
2024-12-16 22:17:18 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def solve(data):
|
2024-12-18 00:39:21 +01:00
|
|
|
O = {k: v for k, v in zip("^>v<", D)}
|
2024-12-16 22:17:18 +01:00
|
|
|
grid, movements = data.split("\n\n")
|
|
|
|
|
grid, H, W = matrix(grid)
|
|
|
|
|
movements = "".join(movements.split())
|
2024-12-18 00:39:21 +01:00
|
|
|
|
|
|
|
|
grid_1 = {
|
|
|
|
|
(r, c): value for r, row in enumerate(grid) for c, value in enumerate(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
grid_2 = {}
|
|
|
|
|
for pos, value in grid_1.items():
|
|
|
|
|
r2, c2 = pos
|
|
|
|
|
match value:
|
2024-12-16 22:17:18 +01:00
|
|
|
case "O":
|
2024-12-18 00:39:21 +01:00
|
|
|
grid_2[(r2, c2 * 2)] = "["
|
|
|
|
|
grid_2[(r2, c2 * 2 + 1)] = "]"
|
2024-12-16 22:17:18 +01:00
|
|
|
case "@":
|
2024-12-18 00:39:21 +01:00
|
|
|
grid_2[(r2, c2 * 2)] = "@"
|
|
|
|
|
grid_2[(r2, c2 * 2 + 1)] = "."
|
2024-12-16 22:17:18 +01:00
|
|
|
case _:
|
2024-12-18 00:39:21 +01:00
|
|
|
grid_2[(r2, c2 * 2)] = value
|
|
|
|
|
grid_2[(r2, c2 * 2 + 1)] = value
|
|
|
|
|
|
|
|
|
|
answers = []
|
|
|
|
|
|
|
|
|
|
for grid, W in [(grid_1, W), (grid_2, W * 2)]:
|
|
|
|
|
pos = next((r, c) for r in range(H) for c in range(W) if grid[(r, c)] == "@")
|
|
|
|
|
|
|
|
|
|
for move in movements:
|
2024-12-16 22:17:18 +01:00
|
|
|
r, c = pos
|
2024-12-18 00:39:21 +01:00
|
|
|
dr, dc = O[move]
|
2024-12-18 12:35:33 +01:00
|
|
|
move_boxes = True
|
|
|
|
|
blocked = False
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
if (r + dr, c + dc) not in grid:
|
|
|
|
|
continue
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
match grid[(r + dr, c + dc)]:
|
|
|
|
|
case ".":
|
|
|
|
|
move_boxes = False
|
|
|
|
|
case "#":
|
|
|
|
|
move_boxes = False
|
|
|
|
|
continue
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
if move_boxes:
|
|
|
|
|
seen = set()
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
Q = [(r + dr, c + dc)]
|
2024-12-18 00:39:21 +01:00
|
|
|
|
|
|
|
|
while Q:
|
|
|
|
|
rr, cc = Q.pop(0)
|
|
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
if (rr, cc) in seen:
|
2024-12-18 00:39:21 +01:00
|
|
|
continue
|
|
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
if (rr, cc) not in grid:
|
|
|
|
|
continue
|
2024-12-18 00:39:21 +01:00
|
|
|
|
|
|
|
|
if grid[(rr, cc)] == "#":
|
2024-12-18 12:35:33 +01:00
|
|
|
blocked = True
|
2024-12-18 00:39:21 +01:00
|
|
|
continue
|
|
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
seen.add((rr, cc))
|
|
|
|
|
|
|
|
|
|
if grid[(rr, cc)] in ".":
|
2024-12-18 00:39:21 +01:00
|
|
|
continue
|
|
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
Q.append((rr + dr, cc + dc))
|
|
|
|
|
if dr != 0:
|
|
|
|
|
match grid[(rr, cc)]:
|
|
|
|
|
case "]":
|
|
|
|
|
Q.append((rr, cc - 1))
|
|
|
|
|
case "[":
|
|
|
|
|
Q.append((rr, cc + 1))
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
if blocked:
|
|
|
|
|
continue
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
patchset = {
|
|
|
|
|
(rr, cc): (rr + dr, cc + dc)
|
|
|
|
|
for rr, cc in seen
|
|
|
|
|
if grid[(rr, cc)] != "."
|
|
|
|
|
}
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
dotset = set(seen) - set(patchset.values())
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
for oldpos, newpos in sorted(patchset.items())[:: -(dr + dc)]:
|
|
|
|
|
value = grid[oldpos]
|
|
|
|
|
grid[newpos] = value
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
for dot in dotset:
|
|
|
|
|
grid[dot] = "."
|
2024-12-18 00:39:21 +01:00
|
|
|
|
2024-12-18 12:35:33 +01:00
|
|
|
grid[(r, c)] = "."
|
|
|
|
|
grid[(r + dr, c + dc)] = "@"
|
|
|
|
|
pos = r + dr, c + dc
|
2024-12-16 22:17:18 +01:00
|
|
|
|
2024-12-18 00:39:21 +01:00
|
|
|
answers.append(sum(k[0] * 100 + k[1] for k, v in grid.items() if v in "O["))
|
|
|
|
|
|
|
|
|
|
p1, p2 = answers
|
|
|
|
|
return p1, p2
|
2024-12-16 22:17:18 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
with open("./input/15.txt", "r") as f:
|
2024-12-18 00:39:21 +01:00
|
|
|
inp = f.read().strip()
|
2024-12-16 22:17:18 +01:00
|
|
|
|
|
|
|
|
p1, p2 = solve(inp)
|
|
|
|
|
|
|
|
|
|
print(p1)
|
|
|
|
|
print(p2)
|