Skip to content

Commit

Permalink
Merge pull request #215 from ephemient/py/day19
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient authored Jan 7, 2025
2 parents af12c1c + f4615cc commit 747b7a5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 15 deletions.
18 changes: 3 additions & 15 deletions py/aoc2024/day19.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Day 19: Linen Layout
"""

from aoc2024.day19c import solve as _solve

SAMPLE_INPUT = """\
r, wr, b, g, bwu, rb, gb, br
Expand All @@ -16,15 +18,6 @@
"""


def _count(keys: list[str], target: str) -> int:
counts = [1]
for i in range(1, len(target) + 1):
counts.append(
sum(counts[i - len(key)] for key in keys if target[:i].endswith(key))
)
return counts[-1]


def solve(data: str) -> str:
"""
>>> print(solve(SAMPLE_INPUT))
Expand All @@ -33,12 +26,7 @@ def solve(data: str) -> str:
"""
keys, *targets = data.splitlines()
keys = keys.split(", ")
part1, part2 = 0, 0
for target in targets:
n = _count(keys, target) if target else None
if n:
part1 += 1
part2 += n
part1, part2 = _solve(keys, targets)
return f"{part1}\n{part2}"


Expand Down
46 changes: 46 additions & 0 deletions py/aoc2024/day19c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# cython: boundscheck=False, wraparound=False, initializedcheck=False, embedsignature=True
import cython
from collections.abc import Collection
from cython.cimports.cpython.mem import PyMem_Free, PyMem_Realloc
from cython.cimports.cpython.unicode import PyUnicode_Tailmatch


@cython.ccall
def solve(
keys: Collection[str], targets: Collection[str]
) -> tuple[cython.int, cython.long]:
i: cython.int
j: cython.int
k: cython.int
numkeys: cython.int = len(keys)
numtargets: cython.int = len(targets)
counts: cython.p_long = cython.NULL
numcounts: cython.int = 0
part1: cython.int = 0
part2: cython.long = 0
try:
for i in range(numtargets):
target: str = targets[i]
if not target:
continue
targetlen: cython.int = len(target)
if numcounts < targetlen + 1:
numcounts = targetlen + 1
counts = cython.cast(
cython.p_long,
PyMem_Realloc(counts, numcounts * cython.sizeof(cython.long)),
)
counts[0] = 1
for j in range(1, targetlen + 1):
counts[j] = 0
for k in range(numkeys):
key: str = keys[k]
keylen: cython.int = len(key)
if PyUnicode_Tailmatch(target, key, 0, j, 1) == 1:
counts[j] += counts[j - keylen]
n: cython.long = counts[targetlen]
part1 += 1 if n else 0
part2 += n
return part1, part2
finally:
PyMem_Free(counts)

0 comments on commit 747b7a5

Please sign in to comment.