StyleInCode

RSS

 

Day 9 - Advent of Code 2025

9 December 2025

Working solutions for the day 9 puzzles.

Part One

""" day_09_01.py """

# usage: python3 day_09_01.py < input

import sys


def area(tile1, tile2):
    """ area of rectangle with opposite corners """
    (x1, y1), (x2, y2) = tile1, tile2
    return (abs(x1 - x2) + 1) * (abs(y1 - y2) + 1)


with sys.stdin as infile:
    tiles = [tuple(map(int, line.split(','))) for line in infile]

areas = [area(t1, t2) for i, t1 in enumerate(tiles[:-1])
         for t2 in tiles[i + 1:]]

print(max(areas))

Part Two - only works for example data - does not scale

""" day_09_02.py """

# usage: python3 day_09_02.py < input

import sys


def points(point1, point2):
    """ points of line segment """
    (x1, y1), (x2, y2) = point1, point2
    if x1 == x2:
        return [(x1, y) for y in range(min(y1, y2), max(y1, y2) + 1)]
    return [(x, y1) for x in range(min(x1, x2), max(x1, x2) + 1)]


with sys.stdin as infile:
    tiles = [tuple(map(int, line.split(','))) for line in infile]

ends = [(t, tiles[(i + 1) % len(tiles)]) for i, t in enumerate(tiles)]

lines = [points(p1, p2) for p1, p2 in ends]
edge_points = {point for line in lines for point in line}


def adjacent(point):
    """ adjacent tiles """
    x, y = point
    return [(x + dx, y + dy) for dx, dy in [(0, -1), (1, 0), (0, 1), (-1, 0)]]


x_min = min(edge_points)[0] - 1
x_max = max(edge_points)[0] + 1
y_min = min(list(zip(*edge_points))[1]) - 1
y_max = max(list(zip(*edge_points))[1]) + 1

explore = [(x_min, y_min)]
empty = set()

while explore:
    tile = explore.pop(-1)
    valid = [(x, y) for x, y in adjacent(tile)
             if all([x_min <= x <= x_max, y_min <= y <= y_max,
                     (x, y) not in edge_points,
                     (x, y) not in explore,
                     (x, y) not in empty])]
    explore.extend(valid)
    empty.add(tile)


def area(tile1, tile2):
    """ area of rectangle with opposite corners """
    (x1, y1), (x2, y2) = tile1, tile2
    return (abs(x1 - x2) + 1) * (abs(y1 - y2) + 1)


def bounds(tile1, tile2):
    """ find opposite corners """
    (x1, y1), (x2, y2) = tile1, tile2
    x0, y0 = min(x1, x2), min(y1, y2)
    x3, y3 = max(x1, x2), max(y1, y2)
    return (x0, y0), (x3, y3)


corners = [(t1, t2) for i, t1 in enumerate(tiles[:-1])
           for t2 in tiles[i + 1:]]

tiled_area = []
for t1, t2 in corners:
    (xl, yl), (xu, yu) = bounds(t1, t2)

    edge = points((xl, yl), (xu, yl))
    edge.extend(points((xu, yl), (xu, yu)))
    edge.extend(points((xu, yu), (xl, yu)))
    edge.extend(points((xl, yu), (xl, yl)))

    if not set(edge) & empty:
        tiled_area.append(area(t1, t2))

print(max(tiled_area))

Categories

Links