day14 make it go fasterrr

This commit is contained in:
Tyrel Souza 2022-12-14 14:00:11 -05:00
parent 1741640930
commit 17652da8ee
No known key found for this signature in database
GPG Key ID: F6582CF1308A2360
3 changed files with 46 additions and 37 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ gif-*
### Python ### ### Python ###
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
profile.out
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class

View File

@ -7,15 +7,6 @@ import functools
SAND_START = [0,500] SAND_START = [0,500]
def get_lines(rows):
_rows = []
for row in rows:
_row = []
for point in row.split(" -> "):
_row.append(list(reversed(list(map(int, point.split(","))))))
_rows.append(_row)
return _rows
def find_bounds(lines): def find_bounds(lines):
x = [] x = []
y = [] y = []
@ -32,7 +23,7 @@ def part1(rows):
d = sand[1] d = sand[1]
dr = sand[1]+1 dr = sand[1]+1
return next_y, (dl,d,dr) return next_y, (dl,d,dr)
lines = get_lines(rows) lines = [[list(reversed(list(map(int, point.split(","))))) for point in row.split(" -> ")] for row in rows]
(minY,maxY), (minX,maxX) = find_bounds(lines) (minY,maxY), (minX,maxX) = find_bounds(lines)
mx = matrix.matrix_of_size(maxX+2,maxY+2) mx = matrix.matrix_of_size(maxX+2,maxY+2)
walls = [] walls = []
@ -82,55 +73,52 @@ def part1(rows):
print("done", sand_grains) print("done", sand_grains)
@shared.profile
def part2(rows): def part2(rows):
def get_next(sand): lines = [[list(reversed(list(map(int, point.split(","))))) for point in row.split(" -> ")] for row in rows]
next_y = sand[0]+1
dl = sand[1]-1
d = sand[1]
dr = sand[1]+1
return next_y, (dl,d,dr)
def check_air(y,x):
if y == floor:
return False
if (y,x) in walls:
return False
return True
lines = get_lines(rows)
(minY,maxY), (minX,maxX) = find_bounds(lines) (minY,maxY), (minX,maxX) = find_bounds(lines)
walls = set() walls = {}
_between_points = matrix.coords_between_points
for line in lines: for line in lines:
for x in range(len(line)-1): for x in range(len(line)-1):
coords = matrix.coords_between_points(line[x], line[x+1]) coords = matrix.coords_between_points(line[x], line[x+1])
for c in coords: for c in coords:
walls.add(c) walls[c] = "#"
for y,x in walls: for y,x in walls:
walls.add((y,x)) walls[(y,x)] = "#"# .add((y,x))
floor = maxY + 2 floor = maxY + 2
sand_grains = -1 sand_grains = -1
while True: while True:
sand_grains += 1 sand_grains += 1
sand = [0,500] sand = [0,500]
if tuple(sand) in walls: if tuple(sand) in walls:
print("done", sand_grains) print("done", sand_grains)
break break
while True: while True:
next_y, (dl, d, dr) = get_next(sand) next_y = sand[0]+1
if check_air(next_y, d): dl = sand[1]-1
dr = sand[1]+1
if next_y == floor:
# hit the floor
walls[tuple(sand)] = "#" # Draw stop
break
elif (next_y, sand[1]) not in walls:
sand[0] = next_y sand[0] = next_y
elif check_air(next_y,dl): elif (next_y, dl) not in walls:
sand[0] = next_y sand[0] = next_y
sand[1] = dl sand[1] = dl
elif check_air(next_y, dr): elif (next_y, dr) not in walls:
sand[0] = next_y sand[0] = next_y
sand[1] = dr sand[1] = dr
else: else:
walls.add(tuple(sand)) # Hit something flat
walls[tuple(sand)] = "#"
break break
#matrix.view_matrix(mx, 0,minX-1, maxY+3,maxX+2)
def main(): def main():
rows = [row for row in shared.load_rows(14)] rows = [row for row in shared.load_rows(14)]
@ -138,8 +126,8 @@ def main():
part1(rows) part1(rows)
print("🕒", elapsed()) print("🕒", elapsed())
with shared.elapsed_timer() as elapsed: with shared.elapsed_timer() as elapsed:
part2(rows) part2(rows)
print("🕒", elapsed()) print("🕒", elapsed())
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,6 +1,26 @@
from contextlib import contextmanager from contextlib import contextmanager
from timeit import default_timer from timeit import default_timer
from pathlib import Path from pathlib import Path
import cProfile
import functools
import pstats
def profile(func):
@functools.wraps(func)
def inner(*args, **kwargs):
profiler = cProfile.Profile()
profiler.enable()
try:
retval = func(*args, **kwargs)
finally:
profiler.disable()
with open('profile.out', 'w') as profile_file:
stats = pstats.Stats(profiler, stream=profile_file)
stats.print_stats()
return retval
return inner
spl = lambda y: [int(w) for w in y] spl = lambda y: [int(w) for w in y]