Skip to content

Commit

Permalink
2024 day 12 parts 1
Browse files Browse the repository at this point in the history
  • Loading branch information
lancelote committed Dec 15, 2024
1 parent cb2e955 commit 1d1d1eb
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
- 2021 - ★★★★★ ★★★★★ ★★★★★ ★★★
- 2022 - ★★★★★ ★★★★★ ★★★★★ ★☆
- 2023 - ★★★★★ ★★★★★ ★★★★★ ★★★☆
- 2024 - ★★★★★ ★★★★★ ★
- 2024 - ★★★★★ ★★★★★ ★

## How to use

Expand Down
77 changes: 77 additions & 0 deletions src/year2024/day12a.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""2024 - Day 12 Part 1: Garden Groups"""

from __future__ import annotations

SHIFTS = (
# r c
(-1, 0), # up
(0, +1), # right
(+1, 0), # down
(0, -1), # left
)


class Region:
def __init__(self, key: str, area: int = 1, perimeter: int = 0) -> None:
self.key = key
self.area = area
self.perimeter = perimeter

@classmethod
def from_point(
cls, sr: int, sc: int, data: list[str], seen: set[tuple[int, int]]
) -> Region:
rows = len(data)
cols = len(data[0])

region = Region(key=data[sr][sc])
to_process = [(sr, sc)]

while to_process:
r, c = to_process.pop()

for dr, dc in SHIFTS:
nr = r + dr
nc = c + dc

if not (0 <= nr < rows and 0 <= nc < cols):
region.perimeter += 1
# todo: flaky false positive below
elif data[nr][nc] != region.key:
region.perimeter += 1
elif (nr, nc) not in seen:
region.area += 1
to_process.append((nr, nc))
seen.add((nr, nc))

return region

@property
def price(self) -> int:
return self.area * self.perimeter

def __str__(self) -> str:
return f"Region(key='{self.key}')"


def parse_regions(data: list[str]) -> list[Region]:
rows = len(data)
cols = len(data[0])

seen: set[tuple[int, int]] = set()
regions: list[Region] = []

for r in range(rows):
for c in range(cols):
if (r, c) not in seen:
seen.add((r, c))
region = Region.from_point(r, c, data, seen)
regions.append(region)

return regions


def solve(task: str) -> int:
data = task.split("\n")
regions = parse_regions(data)
return sum(x.price for x in regions)
48 changes: 48 additions & 0 deletions tests/src/year2024/test_day12a.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""2024 - Day 12 Part 1: Garden Groups"""

from textwrap import dedent

from src.year2024.day12a import solve


def test_solve_1():
task = dedent(
"""
AAAA
BBCD
BBCC
EEEC
"""
).strip()
assert solve(task) == 140


def test_solve_2():
task = dedent(
"""
OOOOO
OXOXO
OOOOO
OXOXO
OOOOO
"""
).strip()
assert solve(task) == 772


def test_solve_3():
task = dedent(
"""
RRRRIICCFF
RRRRIICCCF
VVRRRCCFFF
VVRCCCJFFF
VVVVCJJCFE
VVIVCCJJEE
VVIIICJJEE
MIIIIIJJEE
MIIISIJEEE
MMMISSJEEE
"""
).strip()
assert solve(task) == 1930

0 comments on commit 1d1d1eb

Please sign in to comment.