Solve 75 and 76 in Python.
parent
2802f8e957
commit
d9e31d69cf
115
python/e075.py
115
python/e075.py
|
@ -1,8 +1,119 @@
|
|||
from math import sqrt
|
||||
|
||||
|
||||
def proper_divisors(n):
|
||||
"""
|
||||
Returns the list of divisors for n excluding n.
|
||||
"""
|
||||
if n < 2:
|
||||
return []
|
||||
divisors = [1, ]
|
||||
d = 2
|
||||
while d * d <= n:
|
||||
if n % d == 0:
|
||||
divisors.append(d)
|
||||
d += 1
|
||||
return divisors
|
||||
|
||||
|
||||
def triples_brute_force(b_max):
|
||||
squares = {n * n: n for n in range(1, b_max)}
|
||||
triples = []
|
||||
|
||||
for b in range(3, b_max):
|
||||
for a in range(2, b):
|
||||
c_squared = a * a + b * b
|
||||
if c_squared in squares:
|
||||
triples.append((a, b, squares[c_squared]))
|
||||
return triples
|
||||
|
||||
|
||||
def triples_euclids_formula(m, n):
|
||||
""" Does not return all triples! """
|
||||
assert(m > n)
|
||||
assert(n > 0)
|
||||
a = m * m - n * n
|
||||
b = 2 * m * n
|
||||
c = m * m + n * n
|
||||
return (a, b, c)
|
||||
|
||||
|
||||
def dicksons_method(r):
|
||||
triples = []
|
||||
assert(r % 2 == 0)
|
||||
st = r * r // 2
|
||||
|
||||
for d in proper_divisors(st):
|
||||
s = d
|
||||
t = st // s
|
||||
|
||||
a = r + s
|
||||
b = r + t
|
||||
c = r + s + t
|
||||
L = a + b + c
|
||||
triples.append(L)
|
||||
return sorted(triples)
|
||||
|
||||
|
||||
def dickson_method_min_max_perimeter(r):
|
||||
""" I used this method to check that the min and max
|
||||
perimeter for increasing r are also increasing strictly
|
||||
monotonic. """
|
||||
assert(r % 2 == 0)
|
||||
st = r * r // 2
|
||||
L_min = 10**8
|
||||
L_max = 0
|
||||
|
||||
for d in proper_divisors(st):
|
||||
s = d
|
||||
t = st // s
|
||||
|
||||
L = r + s + r + t + r + s + t
|
||||
if L > L_max:
|
||||
L_max = L
|
||||
if L < L_min:
|
||||
L_min = L
|
||||
return (L_min, L_max)
|
||||
|
||||
|
||||
def dicksons_method_efficient(r):
|
||||
L_max = 1500000
|
||||
perimeters = []
|
||||
assert(r % 2 == 0)
|
||||
st = r * r // 2
|
||||
s_max = int(sqrt(st))
|
||||
for s in range(s_max, 0, -1):
|
||||
if st % s == 0:
|
||||
t = st // s
|
||||
L = r + s + r + t + r + s + t
|
||||
if L > L_max:
|
||||
break
|
||||
perimeters.append(L)
|
||||
else:
|
||||
pass
|
||||
return perimeters
|
||||
|
||||
|
||||
def euler_075():
|
||||
return 0
|
||||
r_max = 258000
|
||||
perimeter_counts = {}
|
||||
|
||||
for r in range(2, r_max, 2):
|
||||
if r % 10000 == 0:
|
||||
print(r)
|
||||
for perimeter in dicksons_method_efficient(r):
|
||||
try:
|
||||
perimeter_counts[perimeter] += 1
|
||||
except KeyError:
|
||||
perimeter_counts[perimeter] = 1
|
||||
|
||||
one_integer_sided_right_triangle_count = 0
|
||||
for perimeter, count in perimeter_counts.items():
|
||||
if count == 1:
|
||||
one_integer_sided_right_triangle_count += 1
|
||||
return one_integer_sided_right_triangle_count
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("e075.py: " + str(euler_075()))
|
||||
assert(euler_075() == 0)
|
||||
# assert(euler_075() == 0)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
from functools import lru_cache
|
||||
|
||||
|
||||
@lru_cache(maxsize=1000000)
|
||||
def possible_sums(n, n_orig, d):
|
||||
if d == n_orig:
|
||||
return 0
|
||||
if n == 0:
|
||||
return 1
|
||||
if n < 0:
|
||||
return 0
|
||||
if d > n:
|
||||
return 0
|
||||
return possible_sums(n - d, n_orig, d) + possible_sums(n, n_orig, d + 1)
|
||||
|
||||
|
||||
def euler_067():
|
||||
return possible_sums(100, 100, 1)
|
||||
|
||||
|
||||
print(euler_067())
|
Loading…
Reference in New Issue