Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def process1(s, part2=False): # Using CSG of boxes.
- # Adapted simpler logic of https://github.com/shaeberling/euler/blob/master/kotlin/src/com/s13g/aoc/aoc2021/Day22.kt.
- lines = s.strip('\n').split('\n')
- state_cuboids = []
- for line in lines:
- state = line[:3].strip()
- cuboid = tuple(tuple(map(int, range_[2:].split('..')))
- for range_ in line[3:].strip().split(','))
- if all(-50 <= c <= 50 for range_ in cuboid for c in range_) or part2:
- state_cuboids.append((state == 'on', cuboid))
- def inside(a, b):
- (ax, ay, az), (bx, by, bz) = a, b
- return (ax[0] >= bx[0] and ay[0] >= by[0] and az[0] >= bz[0] and
- ax[1] <= bx[1] and ay[1] <= by[1] and az[1] <= bz[1])
- def outside(a, b):
- (ax, ay, az), (bx, by, bz) = a, b
- return (ax[0] > bx[1] or ay[0] > by[1] or az[0] > bz[1] or
- ax[1] < bx[0] or ay[1] < by[0] or az[1] < bz[0])
- def subdivide_a_subtracting_b(a, b): # Slow because up to 27 subcells.
- coords = [sorted((a[c][0], a[c][1], b[c][0], b[c][1])) for c in range(3)]
- intervals = [[(c1, c2) for c1, c2 in ((x0, x1 - 1), (x1, x2), (x2 + 1, x3))
- if c1 <= c2]
- for x0, x1, x2, x3 in coords]
- for subcell in itertools.product(*intervals):
- if inside(subcell, a) and not inside(subcell, b):
- yield subcell
- cells = set() # Disjoint union of "on" cubes.
- # Subtract each cuboid from existing cells (potentially subdividing them).
- for state, cuboid in state_cuboids:
- cells_to_add, cells_to_delete = set(), set()
- for cell in cells:
- if outside(cell, cuboid):
- continue
- cells_to_delete.add(cell)
- if not inside(cell, cuboid):
- cells_to_add.update(subdivide_a_subtracting_b(cell, cuboid))
- if state:
- cells_to_add.add(cuboid)
- cells = (cells - cells_to_delete) | cells_to_add
- return sum((np.diff(cell).T[0] + 1).prod() for cell in cells)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement