1
0
Fork 0
advent-of-code/2024/day04.py

60 lines
2.1 KiB
Python
Raw Permalink Normal View History

2024-12-05 09:19:01 +01:00
#!/usr/bin/env python3
with open("./2024/inputs/day04.txt") as f:
puzzle = [l.strip() for l in f.readlines()]
maxY = len(puzzle) - 1
maxX = len(puzzle[0]) - 1
def possible_words(p, start):
y = start[0]
x = start[1]
ret = []
# get the two possible horizontal matches
# skip them if x - 3 < 0 (word would be truncated on the left)
# or x + 3 > maxX (word would be truncated on the right)
if not ((x + 3) > maxX):
ret.append(str(f"{p[y][x]}{p[y][x + 1]}{p[y][x + 2]}{p[y][x + 3]}"))
if not ((x - 3) < 0):
ret.append(str(f"{p[y][x]}{p[y][x - 1]}{p[y][x - 2]}{p[y][x - 3]}"))
# get the two possible vertical matches
# skip them if y - 3 < 0 (word would be truncated on the top)
# or y + 3 > maxY (word would be truncated on the bottom)
if not ((y + 3) > maxY):
ret.append(str(f"{p[y][x]}{p[y + 1][x]}{p[y + 2][x]}{p[y + 3][x]}"))
if not ((y - 3) < 0):
ret.append(str(f"{p[y][x]}{p[y - 1][x]}{p[y - 2][x]}{p[y - 3][x]}"))
# get the four diagonals, again with some (basic) bounds checking
if not ((y + 3) > maxY) and not ((x + 3) > maxX):
ret.append(str(f"{p[y][x]}{p[y + 1][x + 1]}{p[y + 2][x + 2]}{p[y + 3][x + 3]}"))
if not ((y - 3) < 0) and not ((x - 3) < 0):
ret.append(str(f"{p[y][x]}{p[y - 1][x - 1]}{p[y - 2][x - 2]}{p[y - 3][x - 3]}"))
if not ((y + 3) > maxY) and not ((x - 3) < 0):
ret.append(str(f"{p[y][x]}{p[y + 1][x - 1]}{p[y + 2][x - 2]}{p[y + 3][x - 3]}"))
if not ((y - 3) < 0) and not ((x + 3) > maxX):
ret.append(str(f"{p[y][x]}{p[y - 1][x + 1]}{p[y - 2][x + 2]}{p[y - 3][x + 3]}"))
return ret
xmas_count = 0
for y in range(maxY):
for x in range(maxX):
if puzzle[y][x] == "X":
words = possible_words(puzzle, (y, x))
for word in words:
xmas_count += word.count("XMAS")
if puzzle[y][x] == "S":
words = possible_words(puzzle, (y, x))
for word in words:
xmas_count += word.count("SAMX")
print(xmas_count)