euler/python/e719.py

70 lines
1.7 KiB
Python
Raw Normal View History

from typing import List, Optional
from math import sqrt
from functools import lru_cache
def to_int(digits: List[int]) -> int:
return int("".join(map(str, digits)))
def int_len(n: int) -> int:
return len(str(n))
@lru_cache
def digits_make_sum(digits, remainder: int) -> Optional[List]:
if len(digits) == 0:
if remainder == 0:
return []
return None
remainder_digits_count = int_len(remainder)
if remainder_digits_count > len(digits):
return None
if to_int(digits) < remainder:
return None
for group_size in range(1, remainder_digits_count + 1):
digits_list = list(digits)
rest_value = remainder - to_int(digits_list[:group_size])
rest_digits = tuple(digits_list[group_size:])
r = digits_make_sum(rest_digits, rest_value)
if type(r) is list:
return [digits_list[:group_size]] + r
return None
def digits_sum_to(digits, number: int):
r = digits_make_sum(digits, number)
if type(r) is list:
# print(digits, r, number)
return True
return False
def t(limit: int) -> int:
r = 0
for base in range(4, int(sqrt(limit)) + 1):
n = base * base
n_digits = tuple(map(int, list(str(n))))
if digits_sum_to(n_digits, base):
r += n
return r
def euler_719():
assert(t(10**4) == 41333)
assert(digits_sum_to((1, 0, 0), 10) == True)
assert(digits_sum_to((1, 8), 9) == True)
assert(digits_sum_to((2, 5), 5) == False)
assert(digits_sum_to((8, 2, 8, 1), 91) == True)
assert(t(10**6) == 10804656)
return t(10**12)
if __name__ == "__main__":
solution = euler_719()
print("e719.py: " + str(solution))
assert(solution == 128088830547982)