From 17652da8ee9a343f59e54e216f0abffa360b86b0 Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Wed, 14 Dec 2022 14:00:11 -0500 Subject: [PATCH] day14 make it go fasterrr --- .gitignore | 1 + 2022/python/day14.py | 62 +++++++++++++++++-------------------------- 2022/python/shared.py | 20 ++++++++++++++ 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index eb99fdc..e0c9789 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ gif-* ### Python ### # Byte-compiled / optimized / DLL files +profile.out __pycache__/ *.py[cod] *$py.class diff --git a/2022/python/day14.py b/2022/python/day14.py index b078c82..db02f13 100644 --- a/2022/python/day14.py +++ b/2022/python/day14.py @@ -7,15 +7,6 @@ import functools 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): x = [] y = [] @@ -32,7 +23,7 @@ def part1(rows): d = sand[1] dr = sand[1]+1 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) mx = matrix.matrix_of_size(maxX+2,maxY+2) walls = [] @@ -82,55 +73,52 @@ def part1(rows): print("done", sand_grains) +@shared.profile def part2(rows): - def get_next(sand): - 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) + lines = [[list(reversed(list(map(int, point.split(","))))) for point in row.split(" -> ")] for row in rows] (minY,maxY), (minX,maxX) = find_bounds(lines) - walls = set() + walls = {} + _between_points = matrix.coords_between_points for line in lines: for x in range(len(line)-1): coords = matrix.coords_between_points(line[x], line[x+1]) for c in coords: - walls.add(c) + walls[c] = "#" for y,x in walls: - walls.add((y,x)) + walls[(y,x)] = "#"# .add((y,x)) floor = maxY + 2 sand_grains = -1 while True: sand_grains += 1 sand = [0,500] + if tuple(sand) in walls: print("done", sand_grains) break + while True: - next_y, (dl, d, dr) = get_next(sand) - if check_air(next_y, d): + next_y = sand[0]+1 + 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 - elif check_air(next_y,dl): + elif (next_y, dl) not in walls: sand[0] = next_y sand[1] = dl - elif check_air(next_y, dr): + elif (next_y, dr) not in walls: sand[0] = next_y sand[1] = dr + else: - walls.add(tuple(sand)) + # Hit something flat + walls[tuple(sand)] = "#" break - #matrix.view_matrix(mx, 0,minX-1, maxY+3,maxX+2) - - def main(): rows = [row for row in shared.load_rows(14)] @@ -138,8 +126,8 @@ def main(): part1(rows) print("🕒", elapsed()) with shared.elapsed_timer() as elapsed: - part2(rows) - print("🕒", elapsed()) + part2(rows) + print("🕒", elapsed()) if __name__ == "__main__": diff --git a/2022/python/shared.py b/2022/python/shared.py index e252078..5eef667 100644 --- a/2022/python/shared.py +++ b/2022/python/shared.py @@ -1,6 +1,26 @@ from contextlib import contextmanager from timeit import default_timer 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]