From 303eae42c963d0a0ff2278bde6c765755e8fab43 Mon Sep 17 00:00:00 2001 From: felixm Date: Sun, 31 Mar 2024 12:50:44 -0400 Subject: [PATCH] Solve problem 110. --- python/e108.py | 9 +++++- python/e110.py | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 python/e110.py diff --git a/python/e108.py b/python/e108.py index 6288989..5c123e0 100644 --- a/python/e108.py +++ b/python/e108.py @@ -1,4 +1,6 @@ from fractions import Fraction +from lib_misc import proper_divisors +from math import ceil def get_distinct_solutions(n): @@ -16,11 +18,16 @@ def get_distinct_solutions(n): return n_distinct +def get_distinct_solutions2(n): + ds = proper_divisors(n * n) + return ceil((len(ds) + 1) / 2) + + def euler_108(): d_max, n_prev = 0, 0 # I arrived at the starting values empirically by observing the deltas. for n in range(1260, 1000000, 420): - d = get_distinct_solutions(n) + d = get_distinct_solutions2(n) if d > d_max: # print("n={} d={} delta={}".format(n, d, n - n_prev)) n_prev = n diff --git a/python/e110.py b/python/e110.py new file mode 100644 index 0000000..f07734e --- /dev/null +++ b/python/e110.py @@ -0,0 +1,75 @@ +from lib_misc import get_item_counts +from lib_prime import primes + + +def divisors(counts): + r = 1 + for c in counts: + r *= (c + 1) + return r + + +def tau(factors): + orig_factors = factors + factors = factors + factors + counts = get_item_counts(factors) + r = divisors(counts.values()) + p = 1 + for f in orig_factors: + p *= f + return r, p + + +def counters(digits, max_digit): + def incrementing_counters(curr, left, max_digit, result): + if left == 0: + result.append(curr) + return + start = 1 if not curr else curr[-1] + for i in range(start, max_digit + 1): + incrementing_counters(curr + [i], left - 1, max_digit, result) + + result = [] + incrementing_counters([], digits, max_digit, result) + return result + + +def euler_110(): + target = 1000 + target = 4 * 10**6 + threshold = (target * 2) - 1 + psupper = primes(1000) + + lowest_distinct = 0 + lowest_number = 0 + + # find upper bound + for i in range(len(psupper)): + distinct, number = tau(psupper[:i]) + if distinct > threshold: + # print(lowest_distinct, number) + lowest_distinct = distinct + lowest_number = number + psupper = psupper[:i] + + for j in range(1, len(psupper)): + ps = psupper[:-j] + for prime_counts in counters(len(ps), 5): + prime_counts.reverse() + nps = [] + i = 0 + for i in range(len(prime_counts)): + nps += [ps[i]] * prime_counts[i] + nps += ps[i + 1:] + distinct, number = tau(nps) + if distinct > threshold and distinct < lowest_distinct: + lowest_distinct = distinct + lowest_number = number + # print(lowest_distinct, lowest_number) + return lowest_number + + +if __name__ == "__main__": + solution = euler_110() + print("e110.py: " + str(solution)) + assert(solution == 9350130049860600)