StyleInCode

RSS

 

Day 8 - Advent of Code 2025

8 December 2025

Working solutions for the day 8 puzzles.

Part One

""" day_08_01.py """

# usage: python3 day_08_01.py

from itertools import combinations
from math import prod


def get(filename):
    """ contents of filename """
    with open(filename, 'r', encoding='utf-8') as infile:
        data = infile.read()

    return data


def test(data, size, given_solution):
    """ testing """
    assert solve(data, size) == given_solution


def d(p1, p2):
    """ distance squared between p1 and p2 """
    (x1, y1, z1), (x2, y2, z2) = p1, p2
    return abs(x1 - x2) ** 2 + abs(y1 - y2) ** 2 + abs(z1 - z2) ** 2


def already_connected(n1, n2, network):
    """ are n1 and n2 already connected """
    return any(set([n1, n2]) <= ns for _, ns in network.items())


def connected_to(n1, network):
    """ what is n1 connected to """
    return max([i for i, ns in network.items() if n1 in ns] + [-1])


def solve(data, size):
    """ solve the puzzle """
    boxes = [tuple(map(int, row.split(','))) for row in data.splitlines()]

    ds = sorted([[d(j1, j2), j1, j2] for j1, j2 in combinations(boxes, 2)])

    circuits = {}
    i = 0
    for _, j1, j2 in ds[:size]:
        if not already_connected(j1, j2, circuits):
            match (connected_to(j1, circuits), connected_to(j2, circuits)):
                case (-1, -1):
                    circuits[i] = set([j1, j2])
                    i += 1
                case (-1, c) | (c, -1):
                    circuits[c] = circuits[c] | set([j1, j2])
                case (c1, c2):
                    circuits[i] = circuits[c1] | circuits[c2]
                    i += 1
                    del circuits[c1]
                    del circuits[c2]

    return prod(sorted((len(ns) for _, ns in circuits.items()),
                       reverse=True)[:3])


if __name__ == '__main__':
    test(get('example01'), 10, 40)

    puzzle = get('input')
    solution = solve(puzzle, 1000)

    print(solution)

Part Two

""" day_08_02.py """

# usage: python3 day_08_02.py

from itertools import combinations


def get(filename):
    """ contents of filename """
    with open(filename, 'r', encoding='utf-8') as infile:
        data = infile.read()

    return data


def test(data, given_solution):
    """ testing """
    assert solve(data) == given_solution


def d(p1, p2):
    """ distance squared between p1 and p2 """
    (x1, y1, z1), (x2, y2, z2) = p1, p2
    return abs(x1 - x2) ** 2 + abs(y1 - y2) ** 2 + abs(z1 - z2) ** 2


def already_connected(n1, n2, network):
    """ are n1 and n2 already connected """
    return any(set([n1, n2]) <= ns for _, ns in network.items())


def connected_to(n1, network):
    """ what is n1 connected to """
    return max([i for i, ns in network.items() if n1 in ns] + [-1])


def solve(data):
    """ solve the puzzle """
    boxes = [tuple(map(int, row.split(','))) for row in data.splitlines()]

    ds = sorted([[d(j1, j2), j1, j2] for j1, j2 in combinations(boxes, 2)])

    circuits = {}
    i = 0
    for _, j1, j2 in ds:
        if not already_connected(j1, j2, circuits):
            match (connected_to(j1, circuits), connected_to(j2, circuits)):
                case (-1, -1):
                    circuits[i] = set([j1, j2])
                    i += 1
                case (-1, c) | (c, -1):
                    circuits[c] = circuits[c] | set([j1, j2])
                case (c1, c2):
                    circuits[i] = circuits[c1] | circuits[c2]
                    i += 1
                    del circuits[c1]
                    del circuits[c2]

        if len(circuits) == 1:
            bs = next(iter(circuits.values()))
            if len(bs) == len(boxes):
                return j1[0] * j2[0]

    return -1


if __name__ == '__main__':
    test(get('example01'), 25272)

    puzzle = get('input')
    solution = solve(puzzle)

    print(solution)

Categories

Links