Advertisement
hhoppe

Advent of code 2024 day 6 faster

Dec 6th, 2024
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.68 KB | None | 0 0
  1. def day6(s, part2=False):
  2.   grid = np.array([list(line) for line in s.splitlines()])
  3.   ((y0, x0),) = np.argwhere(grid == '^')
  4.   big = max(grid.shape)
  5.   dydx_from_dir = [(0, -1), (-1, 0), (0, 1), (1, 0)]
  6.  
  7.   y, x, dy, dx = y0, x0, -1, 0
  8.   while True:
  9.     grid[y, x] = 'X'
  10.     y1, x1 = y + dy, x + dx
  11.     if not (0 <= y1 < grid.shape[0] and 0 <= x1 < grid.shape[1]):
  12.       break
  13.     if grid[y1, x1] == '#':
  14.       dy, dx = dx, -dy  # Rotate clockwise.
  15.     else:
  16.       y, x = y1, x1
  17.  
  18.   if not part2:
  19.     return (grid == 'X').sum()
  20.  
  21.   jump_steps = np.empty((4, *grid.shape), int)
  22.   for dir in range(4):
  23.     rotated_grid = np.rot90(grid, k=dir)
  24.     rotated_jump_steps = np.rot90(jump_steps[dir], k=dir)
  25.     for y, row in enumerate(rotated_grid):
  26.       num = big
  27.       for x, ch in enumerate(row):
  28.         num = -1 if ch == '#' else num + 1
  29.         rotated_jump_steps[y, x] = num
  30.  
  31.   grid[y0, x0] = '^'
  32.   count = 0
  33.   for (obstacle_y, obstacle_x), ch in np.ndenumerate(grid):
  34.     if ch == 'X':  # Candidate obstacle locations must lie on the original path.
  35.       y, x, dir = y0, x0, 1
  36.       visited = set()
  37.       while True:
  38.         dy, dx = dydx_from_dir[dir]
  39.         steps = min(
  40.           (jump_steps[dir, y, x],)
  41.           + ((abs(d) - 1,) if obstacle_y == y and (d := obstacle_x - x) * dx > 0 else ())
  42.           + ((abs(d) - 1,) if obstacle_x == x and (d := obstacle_y - y) * dy > 0 else ())
  43.         )
  44.         if steps >= big:
  45.           break
  46.         y, x = y + dy * steps, x + dx * steps
  47.         state = y, x, dir
  48.         if state in visited:
  49.           count += 1
  50.           break
  51.         visited.add(state)
  52.         dir = (dir + 1) % 4  # Rotate clockwise.
  53.  
  54.   return count
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement