aoc2023/d24.py

75 lines
2.0 KiB
Python

from lib import *
import sympy as sp
EXAMPLE = """19, 13, 30 @ -2, 1, -2
18, 19, 22 @ -1, -1, -2
20, 25, 34 @ -2, -2, -4
12, 31, 28 @ -1, -2, -1
20, 19, 15 @ 1, -5, -3
"""
def solve1(input: Input):
if len(input.lines()) == 5:
lb = 7
ub = 27
else:
lb = 200000000000000
ub = 400000000000000
# On paper:
# (px - sx1) / vx1 = (py - sy1) / vy1
# (px - sx1) * vy1 = (py - sy1) * vx1
# (px - sx1) * vy1 - (py - sy1) * vx1 = 0
res = 0
eqs = [str_to_ints(l) for l in input.lines()]
for i, eq1 in enumerate(eqs):
for eq2 in eqs[:i]:
sx1, sy1, _, vx1, vy1, _ = eq1
sx2, sy2, _, vx2, vy2, _ = eq2
px, py = sp.symbols("px py")
es = [
vy1 * (px - sx1) - vx1 * (py - sy1),
vy2 * (px - sx2) - vx2 * (py - sy2),
]
r = sp.solve(es)
if not r:
continue
x, y = r[px], r[py]
if lb <= x <= ub and lb <= y < ub:
t1 = (x - sx1) / vx1
t2 = (x - sx2) / vx2
if (t1 > 0 and t2 > 0):
res += 1
return res
def solve2(input: Input):
eqs = [str_to_ints(l) for l in input.lines()]
px, py, pz, vxo, vyo, vzo = sp.symbols("px py pz vxo vyo vzo")
es = []
# The first six equations are enough to find a solution for my problem set.
# Might have to be increased depending on input.
for i, (x, y, z, vx, vy, vz) in enumerate(eqs[:6]):
t = sp.symbols(f"t{i}")
es.append(px + vxo * t - x - vx * t)
es.append(py + vyo * t - y - vy * t)
es.append(pz + vzo * t - z - vz * t)
r = sp.solve(es)[0]
return r[px] + r[py] + r[pz]
def main():
DAY_INPUT = "i24.txt"
print("Solution 1:", solve1(Input(EXAMPLE)))
print("Solution 1:", solve1(Input(DAY_INPUT)))
print("Example 2:", solve2(Input(EXAMPLE)))
print("Solution 2:", solve2(Input(DAY_INPUT)))
return
if __name__ == "__main__":
main()