From 55a9a415cfcccad595054bf6a9d4a279abc0a3b2 Mon Sep 17 00:00:00 2001 From: mindaugl Date: Tue, 8 Apr 2025 15:11:56 +0800 Subject: [PATCH 1/7] Add solution for the Euler project problem 164. --- project_euler/problem_164/__init__.py | 0 project_euler/problem_164/sol1.py | 58 +++++++++++++++++++++++++++ 2 files changed, 58 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 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py new file mode 100644 index 000000000000..97cb085e3508 --- /dev/null +++ b/project_euler/problem_164/sol1.py @@ -0,0 +1,58 @@ +""" +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. + +>>> solution(10) +21838806 +""" + + +def solve( + digit: int, prev: int, prev2: int, sum_max: int, first: bool, cache: dict[str, int] +) -> int: + """ + Solve for remaining 'digit' digits, with previous 'prev' number, and + previous-previous 'prev2' number, total sum of 'sum_max'. + Pass around 'cache' to store/reuse intermediate results. + + >>> solve(1, 0, 0, 9, True, {}) + 9 + >>> solve(1, 0, 0, 9, False, {}) + 10 + """ + if digit == 0: + return 1 + comb = 0 + cache_str = f"{digit},{prev},{prev2}" + if cache_str in cache: + return cache[cache_str] + for v in range(sum_max - prev - prev2 + 1): + if first and v == 0: + continue + comb += solve(digit - 1, v, prev, sum_max, False, 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 + """ + sum_max = 9 + cache: dict[str, int] = {} + ans = solve(n_digits, 0, 0, sum_max, True, cache) + + return ans + + +if __name__ == "__main__": + print(f"{solution(10) = }") From edf973ff418851fd02bc67c67b28d7ddabf72c89 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 5 May 2025 09:45:57 +0300 Subject: [PATCH 2/7] Update sol1.py --- project_euler/problem_164/sol1.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py index 97cb085e3508..35d27d2c745b 100644 --- a/project_euler/problem_164/sol1.py +++ b/project_euler/problem_164/sol1.py @@ -7,9 +7,6 @@ consecutive digits of n have a sum greater than 9? Brute-force recursive solution with caching of intermediate results. - ->>> solution(10) -21838806 """ @@ -46,6 +43,8 @@ def solution(n_digits: int = 20) -> int: >>> solution(2) 45 + >>> solution(10) + 21838806 """ sum_max = 9 cache: dict[str, int] = {} From 2e62f9305eca9ddeade1988a1b242b5ace44539a Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 5 May 2025 09:48:14 +0300 Subject: [PATCH 3/7] Update sol1.py --- project_euler/problem_164/sol1.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py index 35d27d2c745b..b027583b230a 100644 --- a/project_euler/problem_164/sol1.py +++ b/project_euler/problem_164/sol1.py @@ -46,11 +46,8 @@ def solution(n_digits: int = 20) -> int: >>> solution(10) 21838806 """ - sum_max = 9 cache: dict[str, int] = {} - ans = solve(n_digits, 0, 0, sum_max, True, cache) - - return ans + return solve(digit=n_digits, prev=0, prev2=0, sum_max=9, first=True, cache=cache) if __name__ == "__main__": From 8952756a0f964b57689c8c90289f9deba6ff1134 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 5 May 2025 09:49:11 +0300 Subject: [PATCH 4/7] Update sol1.py --- project_euler/problem_164/sol1.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py index b027583b230a..f83376ae1ec3 100644 --- a/project_euler/problem_164/sol1.py +++ b/project_euler/problem_164/sol1.py @@ -11,10 +11,10 @@ def solve( - digit: int, prev: int, prev2: int, sum_max: int, first: bool, cache: dict[str, int] + digit: int, prev1: int, prev2: int, sum_max: int, first: bool, cache: dict[str, int] ) -> int: """ - Solve for remaining 'digit' digits, with previous 'prev' number, and + Solve for remaining 'digit' digits, with previous 'prev1' number, and previous-previous 'prev2' number, total sum of 'sum_max'. Pass around 'cache' to store/reuse intermediate results. @@ -26,13 +26,13 @@ def solve( if digit == 0: return 1 comb = 0 - cache_str = f"{digit},{prev},{prev2}" + cache_str = f"{digit},{prev1},{prev2}" if cache_str in cache: return cache[cache_str] - for v in range(sum_max - prev - prev2 + 1): + for v in range(sum_max - prev1 - prev2 + 1): if first and v == 0: continue - comb += solve(digit - 1, v, prev, sum_max, False, cache) + comb += solve(digit - 1, v, prev1, sum_max, False, cache) cache[cache_str] = comb return comb @@ -47,7 +47,7 @@ def solution(n_digits: int = 20) -> int: 21838806 """ cache: dict[str, int] = {} - return solve(digit=n_digits, prev=0, prev2=0, sum_max=9, first=True, cache=cache) + return solve(digit=n_digits, prev1=0, prev2=0, sum_max=9, first=True, cache=cache) if __name__ == "__main__": From 314844a8afd898e7cdae0720b6d05860be259daa Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 5 May 2025 09:52:35 +0300 Subject: [PATCH 5/7] Update sol1.py --- project_euler/problem_164/sol1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py index f83376ae1ec3..7fc112d40078 100644 --- a/project_euler/problem_164/sol1.py +++ b/project_euler/problem_164/sol1.py @@ -18,9 +18,9 @@ def solve( previous-previous 'prev2' number, total sum of 'sum_max'. Pass around 'cache' to store/reuse intermediate results. - >>> solve(1, 0, 0, 9, True, {}) + >>> solve(digit=1, prev1=0, prev2=0, sum_max=9, first=True, cache={}) 9 - >>> solve(1, 0, 0, 9, False, {}) + >>> solve(digit=1, prev1=0, prev2=0, sum_max=9, first=False, cache={}) 10 """ if digit == 0: @@ -32,7 +32,7 @@ def solve( for v in range(sum_max - prev1 - prev2 + 1): if first and v == 0: continue - comb += solve(digit - 1, v, prev1, sum_max, False, cache) + comb += solve(digit=digit - 1, prev1=v, prev2=prev1, sum_max=sum_max, first=False, cache=cache) cache[cache_str] = comb return comb From 739a54ee7a0c24c7d15ed768eeff4a8545d2ac55 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 06:52:59 +0000 Subject: [PATCH 6/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- project_euler/problem_164/sol1.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py index 7fc112d40078..bd0bf830d8dd 100644 --- a/project_euler/problem_164/sol1.py +++ b/project_euler/problem_164/sol1.py @@ -32,7 +32,14 @@ def solve( for v in range(sum_max - prev1 - prev2 + 1): if first and v == 0: continue - comb += solve(digit=digit - 1, prev1=v, prev2=prev1, sum_max=sum_max, first=False, cache=cache) + comb += solve( + digit=digit - 1, + prev1=v, + prev2=prev1, + sum_max=sum_max, + first=False, + cache=cache, + ) cache[cache_str] = comb return comb From 687726d05e3f0fa821d99de32bc8ec2994fc0460 Mon Sep 17 00:00:00 2001 From: Maxim Smolskiy Date: Mon, 5 May 2025 09:57:41 +0300 Subject: [PATCH 7/7] Update sol1.py --- project_euler/problem_164/sol1.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/project_euler/problem_164/sol1.py b/project_euler/problem_164/sol1.py index bd0bf830d8dd..5387c89bd757 100644 --- a/project_euler/problem_164/sol1.py +++ b/project_euler/problem_164/sol1.py @@ -14,8 +14,8 @@ 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' number, and - previous-previous 'prev2' number, total sum of 'sum_max'. + 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={}) @@ -25,21 +25,25 @@ def solve( """ if digit == 0: return 1 - comb = 0 + cache_str = f"{digit},{prev1},{prev2}" if cache_str in cache: return cache[cache_str] - for v in range(sum_max - prev1 - prev2 + 1): - if first and v == 0: + + comb = 0 + for curr in range(sum_max - prev1 - prev2 + 1): + if first and curr == 0: continue + comb += solve( digit=digit - 1, - prev1=v, + prev1=curr, prev2=prev1, sum_max=sum_max, first=False, cache=cache, ) + cache[cache_str] = comb return comb