Solve problem 387

This commit is contained in:
2026-06-07 10:22:08 -04:00
parent f4dc0e1739
commit fd0cecbbbe
2 changed files with 85 additions and 1 deletions
+84
View File
@@ -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
View File
@@ -68,7 +68,7 @@ def is_prime(n):
def is_prime_rabin_miller(number):
""" 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:
return False