From 145879b8b2546c74fc51446ac607823876a0f601 Mon Sep 17 00:00:00 2001 From: Mindaugas <76015221+mindaugl@users.noreply.github.com> Date: Mon, 5 May 2025 15:00:32 +0800 Subject: [PATCH] Add solution for the Euler project problem 164. (#12663) * Add solution for the Euler project problem 164. * Update sol1.py * Update sol1.py * Update sol1.py * Update sol1.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update sol1.py --------- Co-authored-by: Maxim Smolskiy Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- project_euler/problem_164/__init__.py | 0 project_euler/problem_164/sol1.py | 65 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 project_euler/problem_164/__init__.py create mode 100644 project_euler/problem_164/sol1.py diff --git a/project_euler/problem_164/__init__.py b/project_euler/problem_164/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py new file mode 100644 index 000000000..5387c89bd --- /dev/null +++ b/project_euler/problem_164/sol1.py @@ -0,0 +1,65 @@ +""" +Project Euler Problem 164: https://projecteuler.net/problem=164 + +Three Consecutive Digital Sum Limit + +How many 20 digit numbers n (without any leading zero) exist such that no three +consecutive digits of n have a sum greater than 9? + +Brute-force recursive solution with caching of intermediate results. +""" + + +def solve( + digit: int, prev1: int, prev2: int, sum_max: int, first: bool, cache: dict[str, int] +) -> int: + """ + Solve for remaining 'digit' digits, with previous 'prev1' digit, and + previous-previous 'prev2' digit, total sum of 'sum_max'. + Pass around 'cache' to store/reuse intermediate results. + + >>> solve(digit=1, prev1=0, prev2=0, sum_max=9, first=True, cache={}) + 9 + >>> solve(digit=1, prev1=0, prev2=0, sum_max=9, first=False, cache={}) + 10 + """ + if digit == 0: + return 1 + + cache_str = f"{digit},{prev1},{prev2}" + if cache_str in cache: + return cache[cache_str] + + comb = 0 + for curr in range(sum_max - prev1 - prev2 + 1): + if first and curr == 0: + continue + + comb += solve( + digit=digit - 1, + prev1=curr, + prev2=prev1, + sum_max=sum_max, + first=False, + cache=cache, + ) + + cache[cache_str] = comb + return comb + + +def solution(n_digits: int = 20) -> int: + """ + Solves the problem for n_digits number of digits. + + >>> solution(2) + 45 + >>> solution(10) + 21838806 + """ + cache: dict[str, int] = {} + return solve(digit=n_digits, prev1=0, prev2=0, sum_max=9, first=True, cache=cache) + + +if __name__ == "__main__": + print(f"{solution(10) = }")