Advertisement
hhoppe

Advent of code 2023 day 22

Dec 22nd, 2023 (edited)
828
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.49 KB | None | 0 0
  1. def day22(s, *, part2=False):
  2.   bricks = [tuple(map(int, re.findall(r'\d+', line))) for line in s.splitlines()]
  3.   bricks.sort(key=lambda brick: brick[2])  # In ascending minimum height.
  4.  
  5.   heights = np.full((10, 10), 0)
  6.   occupancy = np.full((10, 10, max(brick[5] for brick in bricks) + 1), -1)  # Empty.
  7.   occupancy[..., 0] = -2  # Fake extra base brick spanning height=0.
  8.   placement, belows = {}, {}
  9.   total = 0
  10.  
  11.   for index, brick in enumerate(bricks):
  12.     footprint = slice(brick[0], brick[3] + 1), slice(brick[1], brick[4] + 1)
  13.     height = heights[footprint].max() + 1
  14.     placement[index] = height
  15.     occupancy[(*footprint, slice(height, height + 1 + brick[5] - brick[2]))] = index
  16.     belows[index] = set(occupancy[(*footprint, height - 1)].flat) - {-1}
  17.     heights[footprint] = height + brick[5] - brick[2]
  18.  
  19.   if not part2:
  20.     for index, brick in enumerate(bricks):
  21.       footprint = slice(brick[0], brick[3] + 1), slice(brick[1], brick[4] + 1)
  22.       height = placement[index]
  23.       height2 = height + 1 + brick[5] - brick[2]
  24.       # Check if for each brick  above this one, there is at least one other brick below it.
  25.       above = set(occupancy[(*footprint, height2)].flat) - {-1}
  26.       total += all(len(belows[index2]) > 1 for index2 in above)
  27.     return total
  28.  
  29.   for index in range(len(bricks)):
  30.     falling = {index}
  31.     for index2 in range(index + 1, len(bricks)):
  32.       if belows[index2] <= falling:
  33.         falling.add(index2)
  34.     total += len(falling) - 1
  35.   return total
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement