93 lines
1.9 KiB
Python
93 lines
1.9 KiB
Python
from lib import get_data
|
|
from lib import Grid2D
|
|
|
|
DIRS = {
|
|
"^": (-1, 0),
|
|
">": (0, 1),
|
|
"v": (1, 0),
|
|
"<": (0, -1),
|
|
}
|
|
|
|
data = get_data(__file__)
|
|
data, moves = data.split("\n\n")
|
|
|
|
g = Grid2D(data)
|
|
|
|
|
|
def simulate(grid: Grid2D, moves: str):
|
|
(p,) = g.find("@")
|
|
for c in moves:
|
|
if c == "\n":
|
|
continue
|
|
d = DIRS[c]
|
|
|
|
to_move = set([p])
|
|
row = to_move
|
|
blocked = False
|
|
while True:
|
|
nrow = set()
|
|
for (
|
|
r,
|
|
c,
|
|
) in row:
|
|
np = r + d[0], c + d[1]
|
|
if g[np] == "#":
|
|
blocked = True
|
|
elif g[np] == "O":
|
|
nrow.add(np)
|
|
elif g[np] == "[":
|
|
nrow.add(np)
|
|
if d == (1, 0) or d == (-1, 0):
|
|
nrow.add((np[0], np[1] + 1))
|
|
elif g[np] == "]":
|
|
if d == (1, 0) or d == (-1, 0):
|
|
nrow.add((np[0], np[1] - 1))
|
|
nrow.add(np)
|
|
to_move |= row
|
|
row = nrow
|
|
if len(row) == 0 or blocked:
|
|
break
|
|
|
|
if not blocked:
|
|
to_place = {}
|
|
p = p[0] + d[0], p[1] + d[1]
|
|
|
|
for tm in to_move:
|
|
np = tm[0] + d[0], tm[1] + d[1]
|
|
to_place[np] = g[tm]
|
|
g[tm] = "."
|
|
|
|
for pos, c in to_place.items():
|
|
g[pos] = c
|
|
|
|
|
|
def score(g: Grid2D) -> int:
|
|
os = g.find("O")
|
|
if os:
|
|
return sum(r * 100 + c for r, c in os)
|
|
return sum(r * 100 + c for r, c in g.find("["))
|
|
|
|
|
|
simulate(g, moves)
|
|
print(score(g))
|
|
|
|
ndata = ""
|
|
for c in data:
|
|
if c == "#":
|
|
ndata += "##"
|
|
elif c == "O":
|
|
ndata += "[]"
|
|
elif c == ".":
|
|
ndata += ".."
|
|
elif c == "@":
|
|
ndata += "@."
|
|
else:
|
|
ndata += c
|
|
|
|
g = Grid2D(ndata)
|
|
(p,) = g.find("@")
|
|
|
|
simulate(g, moves)
|
|
print(score(g))
|
|
exit()
|