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)
