Advertisement
botimoo

2023 D22

Dec 22nd, 2023 (edited)
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.51 KB | Software | 0 0
  1. import sys
  2.  
  3. part = int(sys.argv[1]) if len(sys.argv) > 1 else 1
  4. inType = sys.argv[2] if len(sys.argv) > 2 else "i"
  5. inFile = "inputs/input.in" if inType != "e" else "inputs/example.in"
  6.  
  7.  
  8. def simulateFall(bricks):
  9.     n = len(bricks)
  10.  
  11.     supports = {i: [] for i in range(n)}
  12.     supportedBy = {i: [] for i in range(n)}
  13.  
  14.     settled = {}
  15.  
  16.     for brick in bricks:
  17.         end1, end2, bId = brick
  18.         (x1, y1, z1), (x2, y2, z2) = end1, end2
  19.  
  20.         supporters = []
  21.         while z1 > 1 and len(supporters) == 0:
  22.             for x in range(x1, x2+1):
  23.                 for y in range(y1, y2+1):
  24.                     for z in range(z1, z2+1):
  25.                         if (x, y, z-1) in settled:
  26.                             supporters.append((x, y, z-1))
  27.  
  28.             if len(supporters) == 0:
  29.                 z1 -= 1
  30.                 z2 -= 1
  31.  
  32.         for x in range(x1, x2+1):
  33.             for y in range(y1, y2+1):
  34.                 for z in range(z1, z2+1):
  35.                     settled[(x, y, z)] = bId
  36.  
  37.         for sId in set(settled[sup] for sup in supporters):
  38.             supports[sId].append(bId)
  39.             supportedBy[bId].append(sId)
  40.  
  41.     return supports, supportedBy
  42.  
  43.  
  44. def countRemovable(supports, supportedBy):
  45.     count = 0
  46.     for bId in supports:
  47.         canBeRemoved = True
  48.         for sId in supports[bId]:
  49.             if len(supportedBy[sId]) == 1:
  50.                 canBeRemoved = False
  51.                 break
  52.  
  53.         if canBeRemoved:
  54.             count += 1
  55.  
  56.     return count
  57.  
  58.  
  59. def countChainReaction(supports, supportedBy):
  60.     count = 0
  61.     for bId in supports:
  62.         toCheck = supports[bId].copy()
  63.         falling = {bId}
  64.  
  65.         while toCheck:
  66.             curId = toCheck.pop(0)
  67.  
  68.             if all(sId in falling for sId in supportedBy[curId]):
  69.                 falling.add(curId)
  70.                 toCheck += supports[curId]
  71.  
  72.         count += len(falling) - 1
  73.  
  74.     return count
  75.  
  76.  
  77. bricks = []
  78. with open(inFile) as f:
  79.     i = 0
  80.     for line in f.readlines():
  81.         brick = [[int(n) for n in end.split(",")]
  82.                  for end in line.strip().split("~")]
  83.         brick += [i]
  84.  
  85.         bricks.append(brick)
  86.         i += 1
  87. bricks.sort(key=lambda b: b[0][2])
  88.  
  89.  
  90. if part == 1:
  91.     supports, supportedBy = simulateFall(bricks)
  92.  
  93.     removable = countRemovable(supports, supportedBy)
  94.  
  95.     print(removable)
  96. elif part == 2:
  97.     supports, supportedBy = simulateFall(bricks)
  98.  
  99.     otherFalling = countChainReaction(supports, supportedBy)
  100.  
  101.     print(otherFalling)
  102.  
Tags: aoc aoc2023
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement