From cac9e3d793339c22d878551e6e82db2685568dd1 Mon Sep 17 00:00:00 2001 From: Freddy Pringle Date: Fri, 9 Oct 2020 12:56:24 +0200 Subject: [PATCH 1/4] Added solution for Project Euler problem 129. Fixes: #2695 --- project_euler/problem_129/__init__.py | 0 project_euler/problem_129/sol1.py | 46 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 project_euler/problem_129/__init__.py create mode 100644 project_euler/problem_129/sol1.py diff --git a/project_euler/problem_129/__init__.py b/project_euler/problem_129/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/project_euler/problem_129/sol1.py b/project_euler/problem_129/sol1.py new file mode 100644 index 000000000000..cdda28a62af0 --- /dev/null +++ b/project_euler/problem_129/sol1.py @@ -0,0 +1,46 @@ +""" +A number consisting entirely of ones is called a repunit. We shall define R(k) to be +a repunit of length k; for example, R(6) = 111111. + +Given that n is a positive integer and GCD(n, 10) = 1, it can be shown that there +always exists a value, k, for which R(k) is divisible by n, and let A(n) be the least +such value of k; for example, A(7) = 6 and A(41) = 5. + +The least value of n for which A(n) first exceeds ten is 17. + +Find the least value of n for which A(n) first exceeds one-million. +""" + + +def A(n: int) -> int: + """ + Return the least value k such that the Repunit of length k is divisible by n. + >>> A(7) + 6 + >>> A(41) + 5 + >>> A(1234567) + 34020 + """ + if n % 5 == 0 or n % 2 == 0: + return 0 + R = 1 + k = 1 + while R: + R = (10 * R + 1) % n + k += 1 + return k + + +def solution(limit: int = 1000000) -> int: + """ + Return the least value of n for which A(n) first exceeds limit. + """ + n = limit - 1 + while A(n) <= limit: + n += 2 + return n + + +if __name__ == "__main__": + print(solution()) From 8a4f1b33d214660f52c57d55cc7f0b293e6494af Mon Sep 17 00:00:00 2001 From: Freddy Pringle Date: Sat, 10 Oct 2020 10:24:34 +0200 Subject: [PATCH 2/4] Added doctest for solution() in project_euler/problem_129/sol1.py --- project_euler/problem_129/sol1.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/project_euler/problem_129/sol1.py b/project_euler/problem_129/sol1.py index cdda28a62af0..0d8961795f6b 100644 --- a/project_euler/problem_129/sol1.py +++ b/project_euler/problem_129/sol1.py @@ -35,6 +35,8 @@ def A(n: int) -> int: def solution(limit: int = 1000000) -> int: """ Return the least value of n for which A(n) first exceeds limit. + >>> solution(10) + 17 """ n = limit - 1 while A(n) <= limit: From a67afe7e326d1630b0cb69e3eb4c85acefa8e0dd Mon Sep 17 00:00:00 2001 From: Freddy Pringle Date: Thu, 15 Oct 2020 10:02:52 +0200 Subject: [PATCH 3/4] Update formatting. Reference: #3256 --- project_euler/problem_129/sol1.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/project_euler/problem_129/sol1.py b/project_euler/problem_129/sol1.py index 0d8961795f6b..5b1b52058d13 100644 --- a/project_euler/problem_129/sol1.py +++ b/project_euler/problem_129/sol1.py @@ -1,4 +1,6 @@ """ +Project Euler Problem 129: https://projecteuler.net/problem=129 + A number consisting entirely of ones is called a repunit. We shall define R(k) to be a repunit of length k; for example, R(6) = 111111. @@ -45,4 +47,4 @@ def solution(limit: int = 1000000) -> int: if __name__ == "__main__": - print(solution()) + print(f"{solution() = }") From 997e2e703eb2c4273178535df43c19df8e9ce016 Mon Sep 17 00:00:00 2001 From: Freddy Pringle Date: Thu, 15 Oct 2020 13:22:04 +0200 Subject: [PATCH 4/4] More descriptive function and variable names, more doctests. --- project_euler/problem_129/sol1.py | 41 ++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/project_euler/problem_129/sol1.py b/project_euler/problem_129/sol1.py index 5b1b52058d13..8afe82df162e 100644 --- a/project_euler/problem_129/sol1.py +++ b/project_euler/problem_129/sol1.py @@ -14,36 +14,43 @@ """ -def A(n: int) -> int: +def least_divisible_repunit(divisor: int) -> int: """ - Return the least value k such that the Repunit of length k is divisible by n. - >>> A(7) + Return the least value k such that the Repunit of length k is divisible by divisor. + >>> least_divisible_repunit(7) 6 - >>> A(41) + >>> least_divisible_repunit(41) 5 - >>> A(1234567) + >>> least_divisible_repunit(1234567) 34020 """ - if n % 5 == 0 or n % 2 == 0: + if divisor % 5 == 0 or divisor % 2 == 0: return 0 - R = 1 - k = 1 - while R: - R = (10 * R + 1) % n - k += 1 - return k + repunit = 1 + repunit_index = 1 + while repunit: + repunit = (10 * repunit + 1) % divisor + repunit_index += 1 + return repunit_index def solution(limit: int = 1000000) -> int: """ - Return the least value of n for which A(n) first exceeds limit. + Return the least value of n for which least_divisible_repunit(n) + first exceeds limit. >>> solution(10) 17 + >>> solution(100) + 109 + >>> solution(1000) + 1017 """ - n = limit - 1 - while A(n) <= limit: - n += 2 - return n + divisor = limit - 1 + if divisor % 2 == 0: + divisor += 1 + while least_divisible_repunit(divisor) <= limit: + divisor += 2 + return divisor if __name__ == "__main__":