Solve problem 110.
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
|
from lib_misc import proper_divisors
|
||||||
|
from math import ceil
|
||||||
|
|
||||||
|
|
||||||
def get_distinct_solutions(n):
|
def get_distinct_solutions(n):
|
||||||
@@ -16,11 +18,16 @@ def get_distinct_solutions(n):
|
|||||||
return n_distinct
|
return n_distinct
|
||||||
|
|
||||||
|
|
||||||
|
def get_distinct_solutions2(n):
|
||||||
|
ds = proper_divisors(n * n)
|
||||||
|
return ceil((len(ds) + 1) / 2)
|
||||||
|
|
||||||
|
|
||||||
def euler_108():
|
def euler_108():
|
||||||
d_max, n_prev = 0, 0
|
d_max, n_prev = 0, 0
|
||||||
# I arrived at the starting values empirically by observing the deltas.
|
# I arrived at the starting values empirically by observing the deltas.
|
||||||
for n in range(1260, 1000000, 420):
|
for n in range(1260, 1000000, 420):
|
||||||
d = get_distinct_solutions(n)
|
d = get_distinct_solutions2(n)
|
||||||
if d > d_max:
|
if d > d_max:
|
||||||
# print("n={} d={} delta={}".format(n, d, n - n_prev))
|
# print("n={} d={} delta={}".format(n, d, n - n_prev))
|
||||||
n_prev = n
|
n_prev = n
|
||||||
|
|||||||
75
python/e110.py
Normal file
75
python/e110.py
Normal file
@@ -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)
|
||||||
Reference in New Issue
Block a user