Advertisement
hhoppe

Advent of code 2022 day 17

Dec 17th, 2022 (edited)
936
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.44 KB | None | 0 0
  1. def day17(s, *, part2=False, num=10**12, rocks_in_part2=8_000):
  2.   rocks = [np.array(rock, bool)[::-1] for rock in [
  3.     [[1, 1, 1, 1]],
  4.     [[0, 1, 0], [1, 1, 1], [0, 1, 0]],
  5.     [[0, 0, 1], [0, 0, 1], [1, 1, 1]],
  6.     [[1], [1], [1], [1]],
  7.     [[1, 1], [1, 1]]
  8.   ]]
  9.   jet_iterator = itertools.cycle(s)
  10.   num_rocks = rocks_in_part2 if part2 else 2022
  11.   grid = np.full((num_rocks * 4, 7), False)  # (y=0 is at bottom.)
  12.   heights = [0]
  13.  
  14.   for rock in itertools.islice(itertools.cycle(rocks), num_rocks):
  15.     ry, rx = rock.shape
  16.     y, x = heights[-1] + 3, 2
  17.     while True:
  18.       dx = {'<': -1, '>': 1}[next(jet_iterator)]
  19.       if (x + dx >= 0 and x + dx + rx <= 7 and
  20.           not (grid[y:y + ry, x + dx: x + dx + rx] & rock).any()):
  21.         x += dx
  22.       if y > 0 and not (grid[y - 1:y - 1 + ry, x:x + rx] & rock).any():
  23.         y -= 1
  24.       else:
  25.         grid[y:y + ry, x:x + rx] |= rock
  26.         heights.append(max(heights[-1], y + ry))
  27.         break
  28.  
  29.   if not part2:
  30.     return heights[-1]
  31.  
  32.   # Find a repeating sequence of height deltas, starting from the end.
  33.   deltas = np.diff(heights)
  34.   tail = deltas[-rocks_in_part2 // 3:]
  35.   # If next line fails, increase `rocks_in_part2`.
  36.   i0, i1, *_ = [i for i in range(len(deltas) - len(tail) + 1)
  37.                 if all(deltas[i:i + len(tail)] == tail)]
  38.   h0, h1 = heights[i0], heights[i1]
  39.   div, mod = divmod(num - i0, i1 - i0)
  40.   return h0 + div * (h1 - h0) + heights[i0 + mod] - h0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement