Solve problem 214
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
from lib_prime import primes
|
||||
from functools import cache
|
||||
from math import gcd
|
||||
|
||||
|
||||
def get_phi_table(n: int, ps: list[int]) -> list[int]:
|
||||
tbl = [-1] * (n + 2)
|
||||
tbl[1] = 1
|
||||
queue = [(1, 1, 0)]
|
||||
|
||||
while queue:
|
||||
x, phi, pi = queue.pop()
|
||||
for pin in range(pi, len(ps)):
|
||||
p = ps[pin]
|
||||
tbl[p] = p - 1
|
||||
xn = x * p
|
||||
if xn > n:
|
||||
break
|
||||
d = gcd(x, p)
|
||||
phid = tbl[d]
|
||||
assert phid != -1
|
||||
phin = (phi * (p - 1) * d) // phid
|
||||
tbl[xn] = phin
|
||||
queue.append((xn, phin, pin))
|
||||
return tbl
|
||||
|
||||
|
||||
def euler_214():
|
||||
n = 40 * 10**6
|
||||
ps = primes(n)
|
||||
tbl = get_phi_table(n, ps)
|
||||
|
||||
@cache
|
||||
def chain(n: int) -> int:
|
||||
if n == 1:
|
||||
return 1
|
||||
n = tbl[n]
|
||||
return 1 + chain(n)
|
||||
|
||||
s = 0
|
||||
for i in range(len(ps)):
|
||||
p = ps[i]
|
||||
if chain(p) == 25:
|
||||
s += p
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = euler_214()
|
||||
print(f"e214.py: {solution}")
|
||||
assert solution == 1677366278943
|
||||
Reference in New Issue
Block a user