day 22 cleanup

main
magical 2023-12-22 08:54:07 +00:00
parent efd7f887b8
commit 3dff6a2247
1 changed files with 22 additions and 39 deletions

View File

@ -3,7 +3,7 @@ def overlaps(brick1, brick2):
# the bricks as a whole overlap if there is any overlap # the bricks as a whole overlap if there is any overlap
# on all three axes # on all three axes
for (a,b),(x,y) in zip(brick1, brick2): for (a,b),(x,y) in zip(brick1, brick2):
if (b < x or a > y): if (b < x or a > y):
# ranges don't overlap # ranges don't overlap
return False return False
return True return True
@ -38,7 +38,7 @@ def solve(f):
check(data) check(data)
settle(data) settle(data)
check(data) check(data)
#disintegrate(data) disintegrate(data)
cascade(data) cascade(data)
def settle(data): def settle(data):
@ -46,26 +46,28 @@ def settle(data):
return b[2] return b[2]
data.sort(key=zindex) data.sort(key=zindex)
top = 1 top = 1
for i in range(len(data)): for i in range(len(data)):
# first, lower all blocks >i so that at least one block is at z=top # first, lower to just above the top of the highest block
minz = min(z[0] for x,y,z in data[i:])
if minz > top:
print("lowering all blocks by", minz-top)
for b in data[i:]:
b[:] = lower(b, minz-top)
# lower blocks one at a time
b = data[i] b = data[i]
z = b[2][0]
if z > top:
#print("lowering block %d by %d" % (i, z-top))
b = lower(b, z-top)
# lower block one at a time
n = 0 n = 0
while canlower(b, data[:i]): under = data[:i]
while canlower(b, under):
b = lower(b) b = lower(b)
n += 1 n += 1
print("lowering block %d by %d" % (i,n)) print("lowering block %d by %d+%d" % (i,z-top,n))
data[i] = b data[i] = b
top = max(z[1] for x,y,z in data[:i+1]) + 1 top = max(top, b[2][1] + 1)
# FIXME: should probably re-sort the data here,
# but it seems to work even if we don't
def canlower(block, under): def canlower(block, under):
@ -86,10 +88,8 @@ def disintegrate(data):
for i,x in enumerate(data): for i,x in enumerate(data):
# disintegrate x # disintegrate x
# find other blocks on the same z
#others = [y for y in data if x != y and not (y[2][1] < x[2][0] or y[2][0] > x[2][1])]
# see if any block can be lowered # see if any block above x can be lowered
# if yes, then x cannot be disintegrated # if yes, then x cannot be disintegrated
candisintegrate = True candisintegrate = True
for j in range(i+1, len(data)): for j in range(i+1, len(data)):
@ -97,28 +97,14 @@ def disintegrate(data):
candisintegrate = False candisintegrate = False
break break
#ly = lower(y)
#if y == ly:
# continue
#supports = [z for z in others if z != x and z != y and overlaps(z,ly)]
#if supports:
# # theer is a block that supports y
# #candisintegrate = True
# print('y = %s would be blocked by %d blocks' % (y, len(supports)))
# pass
#else:
# # no block would stop y from falling
# print("no blockk stops y=%s" % (y))
# candisintegrate = False
# break
print(i, x, candisintegrate) print(i, x, candisintegrate)
if candisintegrate: if candisintegrate:
t += 1 t += 1
print(t) print(t)
return (t) return (t)
def cascade(data): def cascade(data):
print(*data, sep="\n") print(*data, sep="\n")
t = 0 t = 0
@ -160,12 +146,9 @@ def cascade(data):
def lower(brick, n=1): def lower(brick, n=1):
"""lower a brick n spaces in the z direction""" """lower a brick n spaces in the z direction"""
x, y, z = brick x, y, z = brick
if z[0] > 1: if z[0] > n:
z = z[0]-1, z[1]-1 z = z[0]-n, z[1]-n
return [x, y, z] return [x, y, z]
import sys import sys
solve(sys.stdin) solve(sys.stdin)