aoc2023/day24.py
2024-11-30 11:27:23 +01:00

70 lines
2.1 KiB
Python

from collections import defaultdict
from itertools import combinations
from tools.aoc import AOCDay
from tools.coordinate import Coordinate, Line
from typing import Any
def get_collisions(hailstones: list[tuple[Coordinate, Coordinate]], area_min: int, area_max: int) -> int:
hailstone_lines = [(pos, Line(pos, pos + vel * area_max)) for pos, vel in hailstones]
count = 0
for (pos1, line1), (pos2, line2) in combinations(hailstone_lines, 2):
try:
intersection = line1.get_intersection(line2)
except ValueError:
continue # do not cross
if area_min <= intersection.x <= area_max and area_min <= intersection.y <= area_max:
count += 1
return count
class Day(AOCDay):
inputs = [
[
(2, "input24_test"),
(15558, "input24"),
],
[
(47, "input24_test"),
(None, "input24"),
],
]
def parse_input(self, part2: bool = False) -> list[tuple[Coordinate, Coordinate]]:
hailstones = []
for line in self.getInput():
p, v = line.split(" @ ")
if part2:
p = Coordinate(*map(int, p.split(", ")))
v = Coordinate(*map(int, v.split(", ")))
else:
p = Coordinate(*map(int, p.split(", ")[:-1]))
v = Coordinate(*map(int, v.split(", ")[:-1]))
hailstones.append((p, v))
return hailstones
def part1(self) -> Any:
if "test" in self._current_test_file:
area_min, area_max = 7, 27
else:
area_min, area_max = 200_000_000_000_000, 400_000_000_000_000
hailstones = self.parse_input()
return get_collisions(hailstones, area_min, area_max)
def part2(self) -> Any:
# moving to position 24, 13, 10 and throwing the rock at velocity -3, 1, 2.
# Maybe we can find some parallel running hailstones and go from there somehow?
hailstones = self.parse_input(True)
return ""
if __name__ == "__main__":
day = Day(2023, 24)
day.run(verbose=True)