advent_of_code_2024/day4/run.py

90 lines
2.6 KiB
Python
Raw Normal View History

2024-12-16 07:54:23 +00:00
from typing import List, Tuple
EXAMPLE = """
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
"""
class FindXMAS:
def __init__(self, input: str) -> None:
self.input = input
self.inputgrid = self._to_grid(self.input)
def __str__(self) -> str:
return f"Part1: {self._part1}\nPart2: {self._part2}"
@property
def _part1(self) -> int:
pass
@property
def _part2(self) -> None:
pass
@staticmethod
def _to_grid(input: str) -> List[List[str]]:
return [list(line) for line in input.splitlines() if line]
def _find_neighbours(
self,
origin: Tuple[int, int],
bounds: Tuple[Tuple[int, int], ...] = ((-1, 1), (-1, 1)),
locations: Tuple[Tuple[int, ...]] = (),
target: str = "XMAS",
) -> Tuple[int, ...]:
if len(target) <= 1:
return locations
current = self.inputgrid[origin[0]][origin[1]]
next = target[target.find(current) + 1]
for row in range(origin[0] + bounds[0][0], origin[0] + bounds[0][1] + 1):
for col in range(origin[1] - bounds[1][0], origin[1] + bounds[1][1] + 1):
if any(
(
row < 0,
row >= len(self.inputgrid[0]),
col < 0,
col >= len(self.inputgrid),
)
):
continue
if self.inputgrid[row][col].upper() == next.upper():
return self._find_neighbours(
origin=(row, col),
bounds=(
(-1 if row < origin[0] else 0, 1 if row > origin[0] else 0),
(-1 if col < origin[1] else 0, 1 if col > origin[1] else 0),
),
locations=(
locations,
(row, col),
),
target=target[1:],
)
2024-12-16 07:54:23 +00:00
def locate_xmas(self) -> List[Tuple[int, int, int, int]]:
location: List[Tuple[int, ...]] = []
2024-12-16 07:54:23 +00:00
for i, line in enumerate(self.inputgrid):
for j, char in enumerate(line):
if char.upper() == "X":
location.append(self._find_neighbours((i, j), target="XMAS"))
2024-12-16 07:54:23 +00:00
return location
2024-12-16 07:54:23 +00:00
if __name__ == "__main__":
example = FindXMAS(EXAMPLE)
print(example._find_neighbours((0, 4)))
print(example.locate_xmas())
# print(example)
# assert example._part1 == 18