Advent of Code 2023 - December 24th
Tags: advent, adventofcode, python, december
Published: 2024-01-01 20:29:37

---
title: Advent of Code 2023 - December 24th
published: true
description: My progress with the 2023 version of Advent of Code
tags: advent, adventofcode, python, december
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36qayk14ewje7rvykeg5.jpg
series: Advent of Code 2023
# published_at: 2023-12-01 17:41 +0000
---

In this series, I'll share my progress with the 2023 version of [Advent of Code](https://adventofcode.com/2023).

Check the first post for a short intro to this series.

You can also follow my progress [on GitHub](https://github.com/robvanderleek/adventofcode).

## December 24th

[The puzzle of day 24](https://adventofcode.com/2023/day/24) was too hard for me :disappointed: This was more of a math puzzle than it was a programming puzzle. I used [this excellent write-up](https://todd.ginsberg.com/post/advent-of-code/2023/day24/) for the first part of the puzzle but could not get the second part to work. In the end, I used [this script](https://topaz.github.io/paste/#XQAAAQCTCQAAAAAAAAA0m0pnuFI8c8h14kUamL+XYzBvHppm9lCBjoan1Q0sYYlqcLWQS0njG9969tZsWjQCla5prwqFlBf7NmX9kjiOCY7TX+bWvefIHPFw0kJtw27ueQjYL0mdn7Q6FDAoLATUFRdcl0NIZ7Ws0uhB+tljhHjpGsc1roo/acxal6l3MZPN/ALVENlwSdFKVmnz6EME/+g78MDO1aQ8PLZcU94Ji3CPqsDOgne3qQDPxCGIQSM/5ne9o/rfay+iN5g5flZBPyTc9wLxTYBt39aGtOJLshNTd0/FMJq5XtqBogaMLjwJ3Sx/DlVP5j+Q/eAqKcuJUAbYzIK2yEIutwdIWvWfAq9eZB5dH6a4Y7UUqYCgB0a1oZJzJ57mJBa7sB+hAmeGOjjDjaGdsrbt0kVL+nzHVzzuHElv8kZxp4nm/oi6nLKS+gfbt5v7tbjxI0vA6KNI7RTF0c7l/U0jGZinbC/TaPPPg/oicam2RfQ2HjlJwChFB6sMiEHJsXU3bP3rd6/Of6VfztN32WlUGSRCkPfyLZS+2XykU0fjYdd0gtU986YbX3tpWTduaOf+mgaaSt17D0VKdsxXV1AvaWDj+uCviXx4yTepZKV2/IpOlewmyC4njPHkcT/g364Zh5+UkgsA4aYPzAxGEUAxVEu2tb8eGJ6iwbHSsqXUdPa5sR82uDJxBfozM8avAcAgK/K40Ud7+zDdUXFjiDe4eq1hB9Qd13wI7lhY6s5bcxB5wtUkGsCBD3n+1xdk+ChVsAgBiasGl368HsiO8fvSO7g3B2VAiay5a9d5xNWjW2aDPkGzO9jJrnfYjluL162BwQX4q6xaaeR0NH4dNw5okgJXUJJGJhhbxPQ0jVbhtV4lRY6ewjZljRK4b+Un6yRmy6g21+8KtwbLoxwDDjzgmpmSypOP4ByIOsZJugqXnTl5g0wb1pAYWTzLAGRX7ReND+BE5uIHOCmBI/nxdEN5pH3TJHhBglmYOuSPmMPY2dKLbLz/n+B6KD/DX7FMlYuMzNZgfJqhQrRhq0mG4G28eM582M5GHGdZvmTfL3xKWtoiB8Xf5aSgSHvjHbuXL7yvU9S88o7fKy8uGNlaZlAWMbR8GzPRuEW8q6AepxqszNFpWNFq+TIpb1TkG7CgCCQ5PupBVRTKh5ap5yE8CjXWotfC7XtaKOSpRbTpHTNr9iQKICftUeSq1Lzse6YbwJ7r0t+9YPhiE6cPjRy+hstAPOZG55HdyQxRjeb8A3n1VnSo3uINnkDxYYhzYeELF3pmiVhDwSYhPJ9+FqAan+pTSEgpu4FXjprXy9aeJcXq1AeEaPpI/96yqPo=) for the second part.

__My pitfall for this puzzle:__ Unfortunately, I do not have the experience (and time) to solve this kind of puzzle.

{% spoiler Solution here, do not click if you want to solve the puzzle first yourself %}

```python
#!/usr/bin/env python3
import random

hail = []
with open('input.txt') as infile:
    lines = infile.readlines()
    for line in lines:
        parts = line.strip().split(' @ ')
        pos = tuple([int(n) for n in parts[0].split(', ')])
        vel = tuple([int(n) for n in parts[1].split(', ')])
        hail.append((pos, vel))

pairs = []
for i in range(len(hail) - 1):
    for j in range(i + 1, len(hail)):
        pairs.append((hail[i], hail[j]))

def collide(h1, h2):
    (x1, y1, z1) = h1[0]
    (vx1, vy1, vz1) = h1[1]
    (x2, y2, z2) = h2[0]
    (vx2, vy2, vz2) = h2[1]
    if vx1 == 0 or vx2 == 0:
        return None
    s1 = vy1 / vx1
    s2 = vy2 / vx2
    if s1 == s2:
        return None
    c1 = y1 - s1 * x1
    c2 = y2 - s2 * x2
    x = (c2 - c1) / (s1 - s2)
    t1 = (x - x1) / vx1
    t2 = (x - x2) / vx2
    if t1 < 0 or t2 < 0:
        return None
    y = s1 * (x - x1) + y1
    return(x, y, int(t1))

def update(hail, dvx, dvy):
    return (hail[0], (hail[1][0] + dvx, hail[1][1] + dvy, hail[1][2]))
     
def predict(hail, t, dvz):
    return hail[0][2] + t * (hail[1][2] + dvz)

def solve():
    while True:
        sel = random.choices(hail, k=4)
        for dvx in range(-500, 500):
            for dvy in range(-500, 500):
                hail0 = update(sel[0], dvx, dvy)
                c1 = collide(hail0, update(sel[1], dvx, dvy))
                c2 = collide(hail0, update(sel[2], dvx, dvy))
                c3 = collide(hail0, update(sel[3], dvx, dvy))
                if c1 and c2 and c3 and c1[0] == c2[0] and c2[0] == c3[0] and \
                    c1[1] == c2[1] and c2[1] == c3[1]:
                    for dvz in range(-500, 500):
                        z1 = predict(sel[1], c1[2], dvz)
                        z2 = predict(sel[2], c2[2], dvz)
                        z3 = predict(sel[3], c3[2], dvz)
                        if z1 == z2 and z2 == z3:
                            return c1[0] + c1[1] + z1

total = 0

minrange = 200000000000000
maxrange = 400000000000000
for p in pairs:
    pos = collide(p[0], p[1])
    if pos:
        if pos[0] >= minrange and pos[0] <= maxrange and \
            pos[1] >= minrange and pos[1] <= maxrange:
            total += 1
print(total)
print(solve())
```

{% endspoiler %}

That's it! See you again tomorrow!