StyleInCode

RSS

 

Day 12 - Advent of Code 2024

12 December 2024

Working solutions for the day 12 puzzles.

Part One

""" day_12_01.py """

# usage: python3 day_12_01.py < input

import sys


def cost(variety, across, down, plot):
    """ cost = area x perimeter for distinct patches """
    def distinct(patch):
        """ list disjoint patches """
        places = set(patch)
        output = []
        while places:
            region = []
            unfinished = True
            while unfinished:
                unfinished = False
                for p in places:
                    if p in region:
                        continue
                    if any([not region, p % across > 0 and p - 1 in region,
                            p - across in region, p + across in region,
                            p % across < across - 1 and p + 1 in region]):
                        region.append(p)
                        unfinished = True
            output.append(region)
            places -= set(region)
        return output

    costs = 0
    for region in distinct([i for i, j in enumerate(plot) if j == variety]):
        perimeter = {}
        for pos in region:
            x, y = pos % across, pos // down
            p = -1 if y == 0 else pos - across
            perimeter[(p, pos)] = perimeter.setdefault((p, pos), 0) + 1
            p = -2 if x == across - 1 else pos + 1
            perimeter[(pos, p)] = perimeter.setdefault((pos, p), 0) + 1
            p = -3 if y == down - 1 else pos + across
            perimeter[(pos, p)] = perimeter.setdefault((pos, p), 0) + 1
            p = -4 if x == 0 else pos - 1
            perimeter[(p, pos)] = perimeter.setdefault((p, pos), 0) + 1

        costs += len(region) * sum(1 for num in perimeter.values() if num == 1)
    return costs


garden = []
width, height = None, None

with sys.stdin as infile:
    for j, line in enumerate(infile):
        for i, plant in enumerate(line.strip()):
            garden.append(plant)
            width = i + 1
        height = j + 1

print(sum(cost(plant, width, height, garden) for plant in set(garden)))

Part Two


Categories

Links