lines = open("input.txt", "r").read().splitlines() sand_source = (500, 0) def parse_rocks(lines: list) -> list: paths = [] for line in lines: path = [int(c) for coord in line.split(" -> ") for c in coord.split(",")] paths.append(path) rocks = [] for path in paths: for i in range(0, len(path) - 2, 2): x1, y1 = path[i], path[i + 1] x2, y2 = path[i + 2], path[i + 3] xrange = range(min(x1, x2), max(x1, x2) + 1) yrange = range(min(y1, y2), max(y1, y2) + 1) coords = [(x, y) for x in xrange for y in yrange] rocks = rocks + list(coords) return list(set(rocks)) def drop_new_sand(sand, rocks, max_y): x, y = sand_source while True: if y > max_y: return sand, False if (x, y + 1) not in rocks and (x, y + 1) not in sand: y += 1 elif (x - 1, y + 1) not in rocks and (x - 1, y + 1) not in sand: x -= 1 y += 1 elif (x + 1, y + 1) not in rocks and (x + 1, y + 1) not in sand: x += 1 y += 1 else: sand.append((x, y)) break return sand, True def get_max_y(rocks): max_y = sorted(rocks, key=lambda x: x[1])[-1][1] return max_y rocks = parse_rocks(lines) max_y = get_max_y(rocks) room_for_sand = True sand = [] while room_for_sand: sand, room_for_sand = drop_new_sand(sand, rocks, max_y) print(len(sand))