You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.2 KiB
84 lines
2.2 KiB
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
from collections import defaultdict
|
|
from copy import deepcopy
|
|
|
|
COORDS = defaultdict(lambda: defaultdict(lambda: '.'))
|
|
MINX = 10000
|
|
MAXX = -10000
|
|
|
|
def parse(line):
|
|
steps = line.split(' -> ')
|
|
ox,oy = map(int,steps[0].split(','))
|
|
COORDS[oy][ox] = '#'
|
|
global MINX,MAXX
|
|
if ox < MINX: MINX = ox
|
|
if ox > MAXX: MAXX = ox
|
|
for s in steps[1:]:
|
|
x,y = map(int,s.split(','))
|
|
if x < MINX: MINX = x
|
|
if x > MAXX: MAXX = x
|
|
if oy == y and ox > x:
|
|
for nx in range(x,ox): COORDS[oy][nx] = '#'
|
|
elif oy == y and x > ox:
|
|
for nx in range(x,ox,-1): COORDS[oy][nx] = '#'
|
|
elif ox == x and y > oy:
|
|
for ny in range(y,oy,-1): COORDS[ny][ox] = '#'
|
|
elif ox == x and oy > y:
|
|
for ny in range(y,oy): COORDS[ny][ox] = '#'
|
|
ox,oy = x,y
|
|
|
|
def show(coords,my,minx,maxx):
|
|
for i in range(my+2):
|
|
l = f'{i:03d} '
|
|
for j in range(minx,maxx+1): l = l + coords[i][j]
|
|
print(l)
|
|
|
|
def fall(coords,my):
|
|
sx,sy = 0,0
|
|
nx,ny = 500,0
|
|
while (sx,sy) != (nx,ny):
|
|
sx,sy = nx,ny
|
|
if coords[sy+1][sx] == '.': ny = sy+1
|
|
elif coords[sy+1][sx-1] == '.':
|
|
ny = sy+1
|
|
nx = sx-1
|
|
elif coords[sy+1][sx+1] == '.':
|
|
ny = sy+1
|
|
nx = sx+1
|
|
if sy > my or ny == 0: return False
|
|
coords[sy][sx] = 'o'
|
|
return True
|
|
|
|
if __name__ == '__main__':
|
|
lines = [parse(line.strip('\n')) for line in open(sys.argv[1])]
|
|
# COORDS[0][500] = '.'
|
|
max_y = max(COORDS.keys())
|
|
show(COORDS,max_y,MINX,MAXX)
|
|
|
|
# challenge 1
|
|
coords1 = deepcopy(COORDS)
|
|
movable = True
|
|
sands = -1
|
|
while movable:
|
|
movable = fall(coords1,max_y)
|
|
sands = sands + 1
|
|
show(coords1,max_y,MINX,MAXX)
|
|
|
|
res1 = str(sands)
|
|
print("challenge 1:" + "\n" + res1 + "\n")
|
|
|
|
# challenge 2
|
|
coords2 = deepcopy(COORDS)
|
|
for x in range(500-max_y-3,500+max_y+4): coords2[max_y+2][x] = '#'
|
|
movable = True
|
|
sands = 0
|
|
while movable:
|
|
movable = fall(coords2,max_y+3)
|
|
sands = sands + 1
|
|
show(coords2,max_y+1,500-max_y-3,500+max_y+4)
|
|
|
|
res2 = str(sands)
|
|
print("challenge 2:" + "\n" + res2 + "\n")
|
|
|
|
|