Skip to content

Commit

Permalink
day24: part1
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-ong committed Dec 24, 2023
1 parent 9006629 commit 24ccfb3
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 7 deletions.
66 changes: 64 additions & 2 deletions day24/day24.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,64 @@
INPUT = "day24/input.txt"
INPUT_SMALL = "day24/input-small.txt"
"""day24 solution"""
from typing import Optional

from day24.lib.classes import Hailstone, Vector2
from day24.lib.parsers import parse_input

INPUT = ("day24/input.txt", Vector2(200000000000000, 400000000000000))
INPUT_SMALL = ("day24/input-small.txt", Vector2(7, 27))


def get_intersection_2d(left: Hailstone, right: Hailstone) -> Optional[Vector2]:
pos1 = left.position.xy
dir1 = left.trajectory.xy
pos2 = right.position.xy
dir2 = right.trajectory.xy

determinant = (dir1.x * dir2.y) - (dir1.y * dir2.x)

if determinant == 0:
return None # parallel

t1 = ((pos2.x - pos1.x) * dir2.y - (pos2.y - pos1.y) * dir2.x) / determinant
t2 = ((pos2.x - pos1.x) * dir1.y - (pos2.y - pos1.y) * dir1.x) / determinant

if t1 < 0: # in the past :(
return None
if t2 < 0: # in the past :(
return None
intersection_point = Vector2(pos1.x + t1 * dir1.x, pos1.y + t1 * dir1.y)
return intersection_point


def within_2d(point: Vector2, min_max: Vector2) -> bool:
return min_max.x <= point.x <= min_max.y and min_max.x <= point.y <= min_max.y


def part1(hailstones: list[Hailstone], valid_range: Vector2) -> int:
result = 0
print(len(hailstones))
left: Hailstone
right: Hailstone
for index, left in enumerate(hailstones[:-1]):
for right in hailstones[index + 1 :]:
intersection: Optional[Vector2] = get_intersection_2d(left, right)

if intersection is None:
continue

if within_2d(intersection, valid_range):
result += 1

return result


def main() -> None:
input_data, valid_range = INPUT

hailstones: list[Hailstone] = parse_input(input_data)
print(len(hailstones))
print(part1(hailstones, valid_range))


if __name__ == "__main__":
main()
18 changes: 14 additions & 4 deletions day24/lib/classes.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
from dataclasses import dataclass


@dataclass(frozen=True)
@dataclass(frozen=True, slots=True)
class Vector3:
x: int
y: int
z: int
x: float
y: float
z: float

@property
def xy(self) -> "Vector2":
return Vector2(self.x, self.y)


@dataclass(frozen=True, slots=True)
class Vector2:
x: float
y: float


@dataclass(frozen=True)
Expand Down
30 changes: 30 additions & 0 deletions day24/tests/test_day24.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from day24.day24 import INPUT_SMALL, get_intersection_2d, part1, within_2d
from day24.lib.classes import Hailstone, Vector2, Vector3
from day24.lib.parsers import parse_input


def test_part1() -> None:
file_path, valid_range = INPUT_SMALL
hailstones: list[Hailstone] = parse_input(file_path)
assert part1(hailstones, valid_range) == 2


def test_get_intersection_2d() -> None:
hailstone_a = Hailstone(Vector3(20, 25, 34), Vector3(-2, -2, -4))
hailstone_b = Hailstone(Vector3(12, 31, 28), Vector3(-1, -2, -1))

assert get_intersection_2d(hailstone_a, hailstone_b) == Vector2(-2, 3)


def test_within_2d() -> None:
valid_range = Vector2(7, 27)
v1 = Vector2(14 + 1 / 3, 15 + 1 / 3)
v2 = Vector2(11 + 6 / 9, 16 + 6 / 9)
v3 = Vector2(6.2, 19.4)
v4 = Vector2(-6, -5)
v5 = Vector2(-2, 3)
assert within_2d(v1, valid_range)
assert within_2d(v2, valid_range)
assert not within_2d(v3, valid_range)
assert not within_2d(v4, valid_range)
assert not within_2d(v5, valid_range)
3 changes: 2 additions & 1 deletion day24/tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def test_vector3() -> None:


def test_parser() -> None:
hailstones: list[Hailstone] = parse_input(INPUT_SMALL)
file_path, _ = INPUT_SMALL
hailstones: list[Hailstone] = parse_input(file_path)

assert len(hailstones) == 5
assert hailstones[0].position == Vector3(19, 13, 30)
Expand Down

0 comments on commit 24ccfb3

Please sign in to comment.