Solve problem 387
This commit is contained in:
@@ -0,0 +1,84 @@
|
|||||||
|
from lib_prime import is_prime_rabin_miller
|
||||||
|
from functools import cache
|
||||||
|
|
||||||
|
def euler_387():
|
||||||
|
harshads = []
|
||||||
|
for n in range(10, 100):
|
||||||
|
ds = n // 10 + n % 10
|
||||||
|
if n % ds == 0:
|
||||||
|
harshads.append((n, ds))
|
||||||
|
limit = 10**14
|
||||||
|
|
||||||
|
r = 0
|
||||||
|
for _ in range(13):
|
||||||
|
new_harshads = []
|
||||||
|
for h, ds in harshads:
|
||||||
|
is_strong = is_prime_rabin_miller(h // ds)
|
||||||
|
for d in range(10):
|
||||||
|
harshad_candidate = h * 10 + d
|
||||||
|
if is_strong and d in (1, 3, 7, 9) and harshad_candidate < limit:
|
||||||
|
if is_prime_rabin_miller(harshad_candidate):
|
||||||
|
r += harshad_candidate
|
||||||
|
nds = ds + d
|
||||||
|
if harshad_candidate % nds != 0:
|
||||||
|
continue
|
||||||
|
new_harshads.append((harshad_candidate, nds))
|
||||||
|
harshads = new_harshads
|
||||||
|
return r
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def digit_sum(n: int) -> int:
|
||||||
|
return sum(map(int, str(n)))
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def is_harshad(n: int) -> bool:
|
||||||
|
return n % digit_sum(n) == 0
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def trunc_right(n: int) -> int:
|
||||||
|
return int(str(n)[:-1])
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def is_strong_harshad(n: int) -> bool:
|
||||||
|
ds = digit_sum(n)
|
||||||
|
if n % ds != 0:
|
||||||
|
return False
|
||||||
|
return is_prime_rabin_miller(n // ds)
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def is_right_trunk_harshad(n: int) -> bool:
|
||||||
|
if n == 0:
|
||||||
|
return False
|
||||||
|
if n < 10:
|
||||||
|
return True
|
||||||
|
if not is_harshad(n):
|
||||||
|
return False
|
||||||
|
return is_right_trunk_harshad(trunc_right(n))
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def is_strong_right_harshad_prime(n: int) -> bool:
|
||||||
|
if not is_prime_rabin_miller(n):
|
||||||
|
return False
|
||||||
|
nt = trunc_right(n)
|
||||||
|
if not is_right_trunk_harshad(nt):
|
||||||
|
return False
|
||||||
|
if not is_strong_harshad(nt):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def asserts():
|
||||||
|
assert is_harshad(201)
|
||||||
|
assert not is_harshad(122)
|
||||||
|
assert trunc_right(201) == 20
|
||||||
|
assert trunc_right(10) == 1
|
||||||
|
assert is_strong_harshad(201)
|
||||||
|
assert is_strong_right_harshad_prime(2011)
|
||||||
|
assert is_right_trunk_harshad(201)
|
||||||
|
assert not is_right_trunk_harshad(1220)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
solution = euler_387()
|
||||||
|
asserts()
|
||||||
|
print("e387.py: " + str(solution))
|
||||||
|
assert(solution == 696067597313468)
|
||||||
|
|
||||||
+1
-1
@@ -68,7 +68,7 @@ def is_prime(n):
|
|||||||
|
|
||||||
def is_prime_rabin_miller(number):
|
def is_prime_rabin_miller(number):
|
||||||
""" Rabin-Miller Primality Test """
|
""" Rabin-Miller Primality Test """
|
||||||
witnesses = [2, 3, 5, 7, 11, 13, 17, 23, 29, 31, 37, 41, 43, 47, 53]
|
witnesses = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
|
||||||
|
|
||||||
if number < 2:
|
if number < 2:
|
||||||
return False
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user