From d9e31d69cfce3ab4f9c12897a629ee92961e6ec9 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Thu, 15 Aug 2019 23:05:39 -0400 Subject: [PATCH] Solve 75 and 76 in Python. --- python/e075.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++++- python/e076.py | 21 +++++++++ 2 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 python/e076.py diff --git a/python/e075.py b/python/e075.py index 655bc61..cdb7cfa 100644 --- a/python/e075.py +++ b/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) diff --git a/python/e076.py b/python/e076.py new file mode 100644 index 0000000..2a6d6a6 --- /dev/null +++ b/python/e076.py @@ -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()) \ No newline at end of file