from enum import Enum from tools.aoc import AOCDay from tools.coordinate import Coordinate from tools.grid import Grid from tools.tools import compare from typing import Any SAND_SOURCE = Coordinate(500, 0) class TType(Enum): AIR = ' ' ROCK = '#' SAND = 'o' class Day(AOCDay): inputs = [ [ (24, "input14_test"), (873, "input14"), ], [ (93, "input14_test"), (24813, "input14"), ] ] def get_cave(self) -> Grid: cave = Grid(TType.AIR) for line in self.getInput(): corners = [] for c in line.split(" -> "): x, y = map(int, c.split(",")) corners.append(Coordinate(x, y)) for i in range(1, len(corners)): for c in corners[i].getLineTo(corners[i-1]): cave.set(c, TType.ROCK) cave.minY = 0 return cave def part1(self) -> Any: cave = self.get_cave() while True: tx, ty = 0, 0 while ty <= cave.maxY: ty += 1 for c in [Coordinate(tx, ty), Coordinate(tx - 1, ty), Coordinate(tx + 1, ty)]: if cave.get(SAND_SOURCE + c) == TType.AIR: tx += compare(c.x, tx) break else: cave.set(SAND_SOURCE + Coordinate(tx, ty - 1), TType.SAND) break else: break return cave.count(TType.SAND) def part2(self) -> Any: cave = self.get_cave() y = cave.maxY + 2 for x in range(cave.minX - 200, cave.maxX + 200): cave.set(Coordinate(x, y), TType.ROCK) while cave.get(SAND_SOURCE) == TType.AIR: tx, ty = 0, 0 while ty <= cave.maxY: ty += 1 for c in [Coordinate(tx, ty), Coordinate(tx - 1, ty), Coordinate(tx + 1, ty)]: if cave.get(SAND_SOURCE + c) == TType.AIR: tx += compare(c.x, tx) break else: cave.set(SAND_SOURCE + Coordinate(tx, ty - 1), TType.SAND) break return cave.count(TType.SAND) if __name__ == '__main__': day = Day(2022, 14) day.run(verbose=True)