1
1
advent-of-code/src/holt59/aoc/2023/day24.py

69 lines
1.8 KiB
Python
Raw Normal View History

2023-12-09 10:01:24 +00:00
import sys
2023-12-25 09:36:29 +00:00
2023-12-30 18:35:06 +00:00
import numpy as np
2023-12-25 09:36:29 +00:00
from sympy import solve, symbols
2023-12-09 10:01:24 +00:00
lines = sys.stdin.read().splitlines()
2023-12-25 09:36:29 +00:00
positions = [
np.array([int(c) for c in line.split("@")[0].strip().split(", ")]) for line in lines
]
velocities = [
np.array([int(c) for c in line.split("@")[1].strip().split(", ")]) for line in lines
]
2023-12-09 10:01:24 +00:00
# part 1
2023-12-25 09:36:29 +00:00
low, high = [7, 27] if len(positions) <= 10 else [200000000000000, 400000000000000]
count = 0
for i, (p1, v1) in enumerate(zip(positions, velocities)):
2023-12-30 18:35:06 +00:00
for p2, v2 in zip(positions[i + 1 :], velocities[i + 1 :]):
2023-12-25 09:36:29 +00:00
p, r = p1[:2], v1[:2]
q, s = p2[:2], v2[:2]
rs = np.cross(r, s)
qpr = np.cross((q - p), r)
if rs == 0:
# assume there are no colinear lines
continue
else:
assert rs != 0
2023-12-30 18:35:06 +00:00
t = np.cross((q - p), s) / rs
2023-12-25 09:36:29 +00:00
u = np.cross((q - p), r) / rs
if t >= 0 and u >= 0:
c = p + t * r
if low <= c[0] <= high and low <= c[1] <= high:
count += 1
answer_1 = count
2023-12-09 10:01:24 +00:00
print(f"answer 1 is {answer_1}")
# part 2
2023-12-25 09:36:29 +00:00
# equation
# p1 + t1 * v1 == p0 + t1 * v0
# p2 + t2 * v2 == p0 + t2 * v0
# p3 + t3 * v3 == p0 + t3 * v0
# ...
# pn + tn * vn == p0 + tn * v0
2023-12-30 18:35:06 +00:00
#
2023-12-25 09:36:29 +00:00
2023-12-30 18:35:06 +00:00
# we can solve with only 3 lines since each lines contains 3
2023-12-25 09:36:29 +00:00
# equations (x / y / z), so 3 lines give 9 equations and 9
# variables: position (3), velocities (3) and times (3).
n = 3
2023-12-30 18:35:06 +00:00
x, y, z, vx, vy, vz, *ts = symbols(
"x y z vx vy vz " + " ".join(f"t{i}" for i in range(n + 1))
)
2023-12-25 09:36:29 +00:00
equations = []
for i, ti in zip(range(n), ts):
for p, d, pi, di in zip((x, y, z), (vx, vy, vz), positions[i], velocities[i]):
equations.append(p + ti * d - pi - ti * di)
r = solve(equations, [x, y, z, vx, vy, vz] + list(ts), dict=True)[0]
answer_2 = r[x] + r[y] + r[z]
2023-12-09 10:01:24 +00:00
print(f"answer 2 is {answer_2}")