87 lines
2.2 KiB
Python
87 lines
2.2 KiB
Python
from collections import deque
|
|
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"),
|
|
(994, "input14_dennis"),
|
|
(873, "input14"),
|
|
],
|
|
[
|
|
(93, "input14_test"),
|
|
(26283, "input14_dennis"),
|
|
(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()
|
|
v = set()
|
|
q = deque()
|
|
q.append(SAND_SOURCE)
|
|
while q:
|
|
current = q.pop()
|
|
if current in v or current.y > cave.maxY + 1:
|
|
continue
|
|
v.add(current)
|
|
for c in [Coordinate(current.x, current.y + 1), Coordinate(current.x - 1, current.y + 1), Coordinate(current.x + 1, current.y + 1)]:
|
|
if cave.get(c) == TType.AIR:
|
|
q.append(c)
|
|
|
|
return len(v)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
day = Day(2022, 14)
|
|
day.run(verbose=True)
|