euler/python/e095.py

49 lines
1.3 KiB
Python

from lib_misc import sum_proper_divisors
def euler_095():
NO_CHAIN = set()
PROPER_DIVISOR_CACHE = {}
def sum_proper_divisors_cached(n):
if n in PROPER_DIVISOR_CACHE:
return PROPER_DIVISOR_CACHE[n]
r = sum_proper_divisors(n)
PROPER_DIVISOR_CACHE[n] = r
return r
def chain(n):
chain = []
next_number = n
while next_number not in chain:
if next_number >= 10**6 or next_number == 0 or next_number in NO_CHAIN:
for c in chain:
NO_CHAIN.add(c)
return None
chain.append(next_number)
next_number = sum_proper_divisors_cached(next_number)
chain.append(next_number)
return chain
chains = [[]]
for i in range(1, 10**6 + 1):
c = chain(i)
if c and c[0] == c[-1]:
if len(c) == len(chains[0]):
# There might be multiple different chains with the same length
# so keep all of them to get the smalles element.
chains.append(c)
elif len(c) > len(chains[0]):
chains = [c]
elems = [e for c in chains for e in c]
return min(elems)
if __name__ == "__main__":
solution = euler_095()
print("e095.py: " + str(solution))
assert(solution == 14316)