Implement 2024 day 4

This commit is contained in:
2024-12-04 12:27:06 +01:00
parent 3e07c8563e
commit 0ce095e9e5
5 changed files with 110 additions and 0 deletions

69
2024/src/aoc/days/day4.py Normal file
View File

@@ -0,0 +1,69 @@
import numpy
from . import SeparateRunner
class DayRunner(SeparateRunner):
@classmethod
def part1(cls, input: str) -> int:
grid = numpy.array(list(map(list, input.strip().split("\n"))))
found = 0
directions = [
(-1, -1),
(-1, 0),
(-1, 1),
(0, -1),
(0, 1),
(1, -1),
(1, 0),
(1, 1),
]
word = "XMAS"
for y in range(grid.shape[0]):
for x in range(grid.shape[1]):
if grid[y, x] != "X":
continue
for dx, dy in directions:
end_x = x + 3 * dx
end_y = y + 3 * dy
if (
end_x < 0
or end_x >= grid.shape[1]
or end_y < 0
or end_y >= grid.shape[0]
):
continue
if all(
grid[y + i * dy, x + i * dx] == c for i, c in enumerate(word)
):
found += 1
return found
@classmethod
def part2(cls, input: str) -> int:
grid = numpy.array(list(map(list, input.strip().split("\n"))))
found = 0
magic = ord("M") ^ ord("S")
for y in range(1, grid.shape[0] - 1):
for x in range(1, grid.shape[1] - 1):
if grid[y, x] != "A":
continue
first_diag = ord(grid[y - 1, x - 1]) ^ ord(grid[y + 1, x + 1])
secnd_diag = ord(grid[y - 1, x + 1]) ^ ord(grid[y + 1, x - 1])
if first_diag == magic and secnd_diag == magic:
found += 1
return found

0
2024/tests/__init__.py Normal file
View File

View File

@@ -0,0 +1,5 @@
..X...
.SAMX.
.A..A.
XMAS.S
.X....

View File

@@ -0,0 +1,10 @@
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX

26
2024/tests/test_day4.py Normal file
View File

@@ -0,0 +1,26 @@
import os
import pytest
from aoc.days.day4 import DayRunner
def get_data(which: int) -> str:
sample = os.path.dirname(__file__) + f"/samples/04.{which}.txt"
with open(sample, mode="rt", encoding="utf-8") as f:
return f.read()
@pytest.mark.parametrize(
"input,answer",
[
(get_data(1), 4),
(get_data(2), 18),
],
)
def test_sample_part1(input: str, answer: int) -> None:
assert DayRunner.part1(input) == answer
def test_sample_part2() -> None:
assert DayRunner.part2(get_data(2)) == 9