day 22 part 1
parent
52a2184a3c
commit
f805d9d373
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
1,0,1~1,2,1
|
||||
0,0,2~2,0,2
|
||||
0,2,3~2,2,3
|
||||
0,0,4~0,2,4
|
||||
2,0,5~2,2,5
|
||||
0,1,6~2,1,6
|
||||
1,1,8~1,1,9
|
|
@ -0,0 +1,133 @@
|
|||
def overlaps(brick1, brick2):
|
||||
"""reports whether two bricks overlap with each other"""
|
||||
# the bricks as a whole overlap if there is any overlap
|
||||
# on all three axes
|
||||
for (a,b),(x,y) in zip(brick1, brick2):
|
||||
if (b < x or a > y):
|
||||
# ranges don't overlap
|
||||
return False
|
||||
return True
|
||||
|
||||
assert overlaps([(0,0), (1,2), (2,2)], [(0,0),(1,1),(2,3)])
|
||||
assert not overlaps([(0,0), (1,1), (2,2)], [(1,1),(1,1),(2,2)])
|
||||
|
||||
|
||||
def read_input(f):
|
||||
data = []
|
||||
for line in f:
|
||||
start, end = line.split("~")
|
||||
start = [int(x) for x in start.split(',')]
|
||||
end = [int(x) for x in end .split(',')]
|
||||
brick = [tuple(sorted([a,b])) for a,b in zip(start,end)]
|
||||
data.append(brick)
|
||||
return data
|
||||
|
||||
def check(data):
|
||||
print(data)
|
||||
for x in data:
|
||||
for y in data:
|
||||
if x == y:
|
||||
assert overlaps(x,y)
|
||||
else:
|
||||
assert not overlaps(x,y)
|
||||
print("ok")
|
||||
|
||||
def solve(f):
|
||||
data = read_input(f)
|
||||
|
||||
check(data)
|
||||
settle(data)
|
||||
check(data)
|
||||
disintegrate(data)
|
||||
|
||||
def settle(data):
|
||||
def zindex(b):
|
||||
return b[2]
|
||||
data.sort(key=zindex)
|
||||
|
||||
|
||||
top = 1
|
||||
for i in range(len(data)):
|
||||
# first, lower all blocks >i so that at least one block is at z=top
|
||||
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]
|
||||
n = 0
|
||||
while canlower(b, data[:i]):
|
||||
b = lower(b)
|
||||
n += 1
|
||||
print("lowering block %d by %d" % (i,n))
|
||||
data[i] = b
|
||||
|
||||
top = max(z[1] for x,y,z in data[:i+1]) + 1
|
||||
|
||||
|
||||
def canlower(block, under):
|
||||
if block[2][0] <= 1:
|
||||
return False
|
||||
x = lower(block)
|
||||
for u in under:
|
||||
if overlaps(u, x):
|
||||
return False
|
||||
return True
|
||||
|
||||
def disintegrate(data):
|
||||
print(*data, sep="\n")
|
||||
t = 0
|
||||
|
||||
#for i,x in enumerate(data):
|
||||
# assert not canlower(x,data[:i])
|
||||
|
||||
for i,x in enumerate(data):
|
||||
# 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
|
||||
# if yes, then x cannot be disintegrated
|
||||
candisintegrate = True
|
||||
for j in range(i+1, len(data)):
|
||||
if canlower(data[j], data[:i] + data[i+1:j]):
|
||||
candisintegrate = False
|
||||
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)
|
||||
if candisintegrate:
|
||||
t += 1
|
||||
print(t)
|
||||
return (t)
|
||||
|
||||
|
||||
|
||||
def lower(brick, n=1):
|
||||
"""lower a brick n spaces in the z direction"""
|
||||
x, y, z = brick
|
||||
if z[0] > 1:
|
||||
z = z[0]-1, z[1]-1
|
||||
return [x, y, z]
|
||||
|
||||
import sys
|
||||
solve(sys.stdin)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue