{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import z3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We don't need to solve for all of the trajectory intersections at once; picking just a handful will do. \n",
"\n",
"There are initially six unknowns (the three components each of $\\overrightarrow{x_{rock}}$ and $\\overrightarrow{v_{rock}}$), and each additional equation adds three equations of the form $x_{i\\cdot rock} + v_{i \\cdot rock} t_n = x_{i\\cdot hail\\cdot n} + v_{i \\cdot hail\\cdot n} t_n$, which also contains one new unknown, the time of intersection $t_n$.\n",
"\n",
"| Hail | Equations | Unknowns |\n",
"| ---- | ----------- | ----------- |\n",
"| 1 | 3 | 7 |\n",
"| 2 | 6 | 8 |\n",
"| 3 | 9 | 9 |\n",
"\n",
"We just need 3 hail trajectories. The first three in the set are enough."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[156689809620606, 243565579389165, 455137247320393, -26, 48, -140],\n",
" [106355761063908, 459832650718033, 351953299411025, 73, -206, -52],\n",
" [271915251832336, 487490927073225, 398003502953444, 31, -414, -304]]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hail = [[int(i) for i in l.replace('@',',').split(',')]\n",
" for l in open('input')]\n",
"\n",
"hail_sample = hail[0:3]\n",
"\n",
"hail_position = [h[0:3] for h in hail_sample]\n",
"hail_velocity = [h[3:] for h in hail_sample]\n",
"\n",
"hail_sample"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"start_position = z3.RealVector('p', 3)\n",
"start_velocity = z3.RealVector('v', 3)\n",
"hit_time = z3.RealVector('t', 3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For each of the hailstone trajectories in the sample, the thrown rock's coordinates will be equal to the hailstone's coordinates at a given time $t$: $x_{i\\cdot rock} + v_{i \\cdot rock} t = x_{i\\cdot hail} + v_{i \\cdot hail} t$ for $i \\in \\{x,\\,y,\\,z\\}$."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"solver = z3.Solver()\n",
"solver.add(*[start_position[i] + start_velocity[i] * t == hp[i] + hv[i] * t\n",
" for t, hp, hv in zip(hit_time, hail_position, hail_velocity) for i in range(3)])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Is the solver satisfied? That is, do none of the constraints conflict with each other?"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"sat"
],
"text/plain": [
"sat"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"solver.check()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The solver model returns the state that satisfies all the constraints:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"[t2 = 474506740599,\n",
" t0 = 931974028142,\n",
" v0 = -337,\n",
" t1 = 829702369046,\n",
" v1 = -6,\n",
" v2 = 155,\n",
" p0 = 446533732372768,\n",
" p2 = 180204909018503,\n",
" p1 = 293892176908833]"
],
"text/plain": [
"[t__2 = 474506740599,\n",
" t__0 = 931974028142,\n",
" v__0 = -337,\n",
" t__1 = 829702369046,\n",
" v__1 = -6,\n",
" v__2 = 155,\n",
" p__0 = 446533732372768,\n",
" p__2 = 180204909018503,\n",
" p__1 = 293892176908833]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"solver.model()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and all that's left to do is extract the results from the state and calculate the answer."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"920630818300104"
],
"text/plain": [
"920630818300104"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"solver.model().eval(sum(start_position))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}