6
votes
Day 24: Never Tell Me The Odds
Today's problem description: https://adventofcode.com/2023/day/24
Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python
with any of the "short names" listed in this page of supported languages):
<details>
<summary>Part 1</summary>
```python
Your code here.
```
</details>
Math is hard so I used ChatGPT to help me with numpy for part 1 (which honestly took so many attempts that it was probably more work than me doing it myself). I figured out the equations for part 2 pretty quickly after seeing the problem but I didn't want to relive high school math & ChatGPT wouldn't give me numpy that worked. So my friend put my equations into Python Z3 lib and then neither of us had to do any math, hooray!
Part 2 explanation
What we have is basically 9 unknowns, and a lot of equations. But we only need to use 3 sets of 3 equations that are linearly independent to solve this.The unknowns we need are px, py, pz, vx, vy, vz, t, s, and r; where t, s, and r are the 3 times of intersection.
So we can determine these by:
px1 + vx1 * t = px + vx * t
py1 + vy1 * t = py + vy * t
pz1 + vz1 * t = pz + vz * t
px2 + vx2 * s = px + vx * s
py2 + vy2 * s = py + vy * s
pz2 + vz2 * s = pz + vz * s
px3 + vx3 * r = px + vx * r
py3 + vy3 * r = py + vy * r
pz3 + vz3 * r = pz + vz * r
Where px1, py1, pz1, vx1, vy1, vz1, etc, are the positions & velocities of the first three points on our list.
(Except we get trolled in the test input and the system is under-determined in the first 3 so we have to look a bit later. TBH I didn't consider this when attempting to solve with numpy, and this might be why I got the wrong answer for the test input, maybe it would've worked if I tried 3 different points. But I don't want to go back and try again.)
Python code
Part 1 went quite smoothly, and I finished at my highest place this year at 122! Not quite the leaderboard, but much better than I was ever expecting to place this year. Nothing tricky, just parsing the input, finding the intersections, and checking the bounds.
Part 2 was not so nice, but I got there eventually. My solution relies on recognizing that if you rotate the vectors at a certain angle, they should all align to intersect at a singular point. I first got stuck trying to figure out how to rotate 3d vectors, but then realized that I don't actually need to rotate the vectors, I can just shift their x and y velocities until they align. My solution simply tries a range of values for the x and y velocities until all hailstones intersect at a singular point, that point being the x and y coordinates for the answer. I then repeat the process for the x and z velocities/coordinates to get the final position.
Haskell Solution
This one was miserable. My solution sounds pretty similar to scarecrw's on the sufrace. The awfulness mostly came from translating linear algebra equations into code. I wouldn't mind doing it on paper, but typing it all out was so error-prone, and I spent hours tracking down mysterious bugs. (I think ChatGPT created most of those bugs, so thanks for nothing, you've been really useless.) I got there eventually, but mostly at the mercy of people who have already done the hard work on StackOverflow. After figuring that out, it was just a matter of brute-forcing guesses until we get a solution. I'm still not even convinced my algorithm is truly correct, since my unit tests felt a little dodgy. But I got the star so I'm ready to forget about it altogether.
C# code - solution runner, ray collision