Pt 1 was easy, Pt 2 was pure horror. Earlier drafts of the code tried to be way too smart. At one point, I just came to the conclusion to place a new obstacle (#) on the grid and just rerun the thing to look for loops. 2 things: - the visited positions from pt 1 can be used as a subset for positions to consider for the extra "#". - The track of loops can be optimized to look at bounces on "#"s instead of each individual y,x pos, given that the direction is remembered. pt 2 is familiar, the last time a puzzle required look detection the puzzle used lazer beams and reflectors. Not sure what Event or day it was.
56 lines
1.2 KiB
Python
56 lines
1.2 KiB
Python
from output import cw, matrix
|
|
|
|
|
|
def solve(data):
|
|
M, H, W = matrix(data)
|
|
|
|
y, x = [(r, c) for r in range(H) for c in range(W) if M[r][c] == "^"][0]
|
|
delta_y, delta_x = (-1, 0)
|
|
seen, _ = travel(M, H, W, y, x, delta_y, delta_x)
|
|
|
|
p1 = len(seen)
|
|
|
|
p2 = 0
|
|
for row, col in seen:
|
|
grid = [list(row) for row in M]
|
|
grid[row][col] = "#"
|
|
_, loop_found = travel(grid, H, W, y, x, delta_y, delta_x)
|
|
|
|
if loop_found:
|
|
p2 += 1
|
|
|
|
return p1, p2
|
|
|
|
|
|
def travel(M, H, W, y, x, delta_y, delta_x):
|
|
seen = set()
|
|
hit = set()
|
|
loop_found = False
|
|
|
|
while True:
|
|
seen.add((y, x))
|
|
|
|
if y == 0 or y == H - 1 or x == 0 or x == W - 1:
|
|
break
|
|
|
|
if M[y + delta_y][x + delta_x] == "#":
|
|
if (y + delta_y, x + delta_x, delta_y, delta_x) in hit:
|
|
loop_found = True
|
|
break
|
|
|
|
hit.add((y + delta_y, x + delta_x, delta_y, delta_x))
|
|
delta_y, delta_x = cw(delta_y, delta_x)
|
|
else:
|
|
y, x = y + delta_y, x + delta_x
|
|
|
|
return seen, loop_found
|
|
|
|
|
|
if __name__ == "__main__":
|
|
with open("./input/06.txt", "r") as f:
|
|
inp = f.read().strip()
|
|
|
|
p1, p2 = solve(inp)
|
|
|
|
print(p1)
|
|
print(p2)
|