Advertisement
hhoppe

Advent of code 2024 day 6

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