From cc65a9f5d8706d3e67b67397e32cddd1ed0e8db9 Mon Sep 17 00:00:00 2001 From: pareronia <49491686+pareronia@users.noreply.github.com> Date: Tue, 12 Dec 2023 22:25:59 +0100 Subject: [PATCH] AoC 2023 Day 12 - faster --- src/main/python/AoC2023_12.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/python/AoC2023_12.py b/src/main/python/AoC2023_12.py index 018c0672..9b5b3446 100644 --- a/src/main/python/AoC2023_12.py +++ b/src/main/python/AoC2023_12.py @@ -27,8 +27,13 @@ """ +def count(s: str, counts: tuple[int, ...]) -> int: + _count.cache_clear() + return _count(s, counts, 0) + + @cache -def count(s: str, counts: tuple[int, ...], idx: int) -> int: +def _count(s: str, counts: tuple[int, ...], idx: int) -> int: # base case: end of s if s == "": if len(counts) == 0 and idx == 0: @@ -44,17 +49,17 @@ def count(s: str, counts: tuple[int, ...], idx: int) -> int: for nxt in nxts: if nxt == "#": # if '#': move to next char in current group - ans += count(s[1:], counts, idx + 1) + ans += _count(s[1:], counts, idx + 1) elif nxt == ".": # if '.' (between groups) if idx > 0: # was in group before if len(counts) > 0 and idx == counts[0]: # finished group matches required -> find next required - ans += count(s[1:], counts[1:], 0) + ans += _count(s[1:], counts[1:], 0) else: # was not in group: keep looking for next group - ans += count(s[1:], counts, 0) + ans += _count(s[1:], counts, 0) else: # should not happen assert False @@ -83,7 +88,7 @@ def brute_force_count(self, s: str, counts: tuple[int, ...]) -> int: def solve( self, input: Input, f: Callable[[str], tuple[str, tuple[int, ...]]] ) -> int: - return sum(count(*f(line), 0) for line in input) + return sum(count(*f(line)) for line in input) def part_1(self, input: Input) -> Output1: def parse(line: str) -> tuple[str, tuple[int, ...]]: