Skip to content

Commit

Permalink
Merge pull request #96 from vil02/25_solution
Browse files Browse the repository at this point in the history
feat: add `adv_2024_25`
  • Loading branch information
vil02 authored Dec 25, 2024
2 parents c5ba1d0 + 340cc05 commit d6e35ff
Show file tree
Hide file tree
Showing 4 changed files with 4,111 additions and 0 deletions.
49 changes: 49 additions & 0 deletions solutions/adv_2024_25.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import itertools


def _get_sizes(in_str: str) -> tuple[int, int]:
lines = in_str.splitlines()
x_size = len(lines[0])
y_size = len(lines)
return x_size, y_size


def _get_height(in_str: str, in_col_num: int) -> int:
_, y_size = _get_sizes(in_str)
lines = in_str.splitlines()
return sum(1 for _ in range(y_size) if lines[_][in_col_num] == "#") - 1


def _heights(in_str: str) -> list[int]:
x_size, _ = _get_sizes(in_str)
return [_get_height(in_str, _) for _ in range(x_size)]


def _is_key(in_str: str) -> bool:
lines = in_str.splitlines()
return set(lines[0]) == {"#"}


def _parse(in_str: str) -> tuple[bool, list[int]]:
return _is_key(in_str), _heights(in_str)


def _parse_input(in_str: str) -> tuple[list[list[int]], list[list[int]]]:
keys = []
locks = []
for _ in in_str.split("\n\n"):
is_key, heights = _parse(_)
if is_key:
keys.append(heights)
else:
locks.append(heights)
return locks, keys


def does_fit(lock: list[int], key: list[int]) -> bool:
return all(_l + _k <= len(lock) for _l, _k in zip(lock, key, strict=True))


def solve_a(in_str: str) -> int:
locks, keys = _parse_input(in_str)
return sum(1 for _l, _k in itertools.product(locks, keys) if does_fit(_l, _k))
24 changes: 24 additions & 0 deletions tests/test_adv_2024_25.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import pytest

import solutions.adv_2024_25 as sol
from . import test_utils as tu


@pytest.mark.parametrize(
("lock", "key", "expected"),
[
([0, 5, 3, 4, 3], [5, 0, 2, 1, 3], False),
([0, 5, 3, 4, 3], [4, 3, 4, 0, 2], False),
([0, 5, 3, 4, 3], [3, 0, 2, 0, 1], True),
([1, 2, 0, 5, 3], [5, 0, 2, 1, 3], False),
([1, 2, 0, 5, 3], [4, 3, 4, 0, 2], True),
([1, 2, 0, 5, 3], [3, 0, 2, 0, 1], True),
],
)
def test_does_fit(lock: list[int], key: list[int], expected: bool) -> None:
assert sol.does_fit(lock, key) == expected


_INPUTS = tu.get_inputs(25, {"small", "p"})

test_solve_a = _INPUTS.get_test(sol.solve_a, {"small": 3, "p": 3090})
Loading

0 comments on commit d6e35ff

Please sign in to comment.