summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2023-12-12 15:59:26 +0000
committerTomasz Kramkowski <tomasz@kramkow.ski>2023-12-12 15:59:26 +0000
commit403e334db290adfa7a64c617c83c4b69e7fc12b6 (patch)
tree040aaf7085ed924e48bf3db06b68dd391eafe49f
parent7a02361e62b282a12f5d693858f7fb2e99a7f029 (diff)
downloadaoc2023-403e334db290adfa7a64c617c83c4b69e7fc12b6.tar.gz
aoc2023-403e334db290adfa7a64c617c83c4b69e7fc12b6.tar.xz
aoc2023-403e334db290adfa7a64c617c83c4b69e7fc12b6.zip
day 12 optimisations
-rw-r--r--12.py20
1 files changed, 16 insertions, 4 deletions
diff --git a/12.py b/12.py
index 2c2810c..065a566 100644
--- a/12.py
+++ b/12.py
@@ -1,22 +1,34 @@
# pyright: strict
-import fnmatch
from functools import cache
from sys import stdin
@cache
+def match(arrangement: str, pattern: str) -> bool:
+ if len(arrangement) != len(pattern):
+ return False
+ for a, p in zip(arrangement, pattern):
+ if p == "?":
+ continue
+ if a != p:
+ return False
+ return True
+
+
+@cache
def matching(
pattern: str, groups: tuple[int, ...], length: int, min_offset: int = 0
) -> int:
if not groups:
return 1 if "#" not in pattern else 0
+ block = "#" * groups[0]
total = 0
for offset in range(min_offset, length - sum(groups) - len(groups) + 2):
- base = "." * offset + "#" * groups[0]
- if not fnmatch.fnmatch(base, pattern[: len(base)]):
+ prefix_len = offset + groups[0]
+ if not match("." * offset + block, pattern[:prefix_len]):
continue
total += matching(
- pattern[len(base) :], groups[1:], length - len(base), min_offset=1
+ pattern[prefix_len:], groups[1:], length - prefix_len, min_offset=1
)
return total