DEV Community

Cover image for Advent of Code 2023 - December 24th
Rob van der Leek
Rob van der Leek

Posted on

Advent of Code 2023 - December 24th

In this series, I'll share my progress with the 2023 version of Advent of Code.

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

You can also follow my progress on GitHub.

December 24th

The puzzle of day 24 was too hard for me 😞 This was more of a math puzzle than it was a programming puzzle. I used this excellent write-up for the first part of the puzzle but could not get the second part to work. In the end, I used this script for the second part.

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

Solution here, do not click if you want to solve the puzzle first yourself
#!/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())
Enter fullscreen mode Exit fullscreen mode

That's it! See you again tomorrow!

Top comments (0)