87 lines
2.6 KiB
Python
Executable file
87 lines
2.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
# https://adventofcode.com/2024/day/4
|
|
|
|
def get_lines(filename: str) -> list:
|
|
with open(filename, "r") as file:
|
|
return [line.strip() for line in file.readlines()]
|
|
|
|
|
|
def get_grid(lines: list) -> list:
|
|
grid = []
|
|
for line in lines:
|
|
row = []
|
|
for char in line:
|
|
row.append(char)
|
|
grid.append(row)
|
|
return grid
|
|
|
|
|
|
def check_xmas_from_pos(grid: list, row: int, col: int,
|
|
direction: tuple, xmas_letters: list) -> bool:
|
|
if grid[row][col] != xmas_letters[0]:
|
|
# wrong letter, end of recursion
|
|
return False
|
|
|
|
if len(xmas_letters) == 1:
|
|
# found the last letter, end of recursion
|
|
return True
|
|
|
|
# out of bounds, end of recursion
|
|
new_row = row + direction[0]
|
|
new_col = col + direction[1]
|
|
if new_row < 0 or new_row >= len(grid):
|
|
return False
|
|
if new_col < 0 or new_col >= len(grid[0]):
|
|
return False
|
|
|
|
# go deeper into recursion with one less letter in the search string
|
|
return check_xmas_from_pos(grid, new_row, new_col, direction, xmas_letters[1:])
|
|
|
|
|
|
def get_xmas_appearances(grid: list) -> int:
|
|
xmas_appearances = 0
|
|
directions = [(0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)]
|
|
xmas_letters = ['X', 'M', 'A', 'S']
|
|
for row in range(len(grid)):
|
|
for col in range(len(grid[0])):
|
|
for direction in directions:
|
|
if check_xmas_from_pos(grid, row, col, direction, xmas_letters):
|
|
xmas_appearances += 1
|
|
return xmas_appearances
|
|
|
|
|
|
def check_cross(grid: list, row: int, col: int) -> bool:
|
|
a1 = grid[row - 1][col - 1]
|
|
a2 = grid[row + 1][col + 1]
|
|
b1 = grid[row - 1][col + 1]
|
|
b2 = grid[row + 1][col - 1]
|
|
if (a1 == "M" and a2 == "S") or (a1 == "S" and a2 == "M"):
|
|
if (b1 == "M" and b2 == "S") or (b1 == "S" and b2 == "M"):
|
|
return True
|
|
return False
|
|
|
|
|
|
def get_cross_mas_appearances(grid: list) -> int:
|
|
cross_mas_appearances = 0
|
|
for row in range(1, len(grid) - 1):
|
|
for col in range(1, len(grid[0]) - 1):
|
|
if grid[row][col] == "A":
|
|
if check_cross(grid, row, col):
|
|
cross_mas_appearances += 1
|
|
return cross_mas_appearances
|
|
|
|
|
|
def main():
|
|
# lines = get_lines("sample-input.txt")
|
|
lines = get_lines("input.txt")
|
|
|
|
grid = get_grid(lines)
|
|
xmas_appearances = get_xmas_appearances(grid)
|
|
print(f"Part 1: The word XMAS appears {xmas_appearances} times.")
|
|
cross_mas_appearances = get_cross_mas_appearances(grid)
|
|
print(f"Part 2: The cross-MAS pattern appears {cross_mas_appearances} times.")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|