diff options
Diffstat (limited to '2022/14/solve.py')
-rw-r--r-- | 2022/14/solve.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/2022/14/solve.py b/2022/14/solve.py new file mode 100644 index 0000000..d327e85 --- /dev/null +++ b/2022/14/solve.py @@ -0,0 +1,71 @@ +data = [ + [[int(d) for d in r.split(",")] for r in dat.split(" -> ")] + for dat in open("input").readlines() + if dat != "" +] + +X = 1000 +Y = 500 +SOURCE = [500, 0] + +AIR = 0 +ROCK = 1 +SAND = 2 +RESTED = 3 + + +def rocks(grid, line): + for i, (x, y) in enumerate(line[1:]): + px = line[i][0] + py = line[i][1] + xmax, xmin = max(x, px), min(x, px) + ymax, ymin = max(y, py), min(y, py) + + for lx in range(xmin, xmax + 1): + for ly in range(ymin, ymax + 1): + grid[lx][ly] = ROCK + + +def simulate(grid): + falling = True + while falling: + # new sand drop! + sand = SOURCE.copy() + while True: + if sand[1] >= Y - 1: + falling = False + break + elif grid[sand[0]][sand[1] + 1] == AIR: + sand[1] += 1 + elif grid[sand[0] - 1][sand[1] + 1] == AIR: + sand[0] -= 1 + sand[1] += 1 + elif grid[sand[0] + 1][sand[1] + 1] == AIR: + sand[0] += 1 + sand[1] += 1 + else: + grid[sand[0]][sand[1]] = RESTED + if sand == SOURCE: + falling = False + break + + +def solve(grounded): + grid = [[AIR] * Y for i in range(X)] + for line in data: + rocks(grid, line) + + if grounded: + ground = max( + max([i for i, y in enumerate(col) if y == ROCK], default=0) + for col in grid + ) + for x in range(X): + grid[x][ground + 2] = ROCK + + simulate(grid) + return sum(col.count(RESTED) for col in grid) + + +print(f"Part 1: {solve(False)}") +print(f"Part 2: {solve(True)}") |