from tools import number_theory def range_n(N): return int(((4 * N + 1) ** 0.5 - 3) / 4) + 1 def range_k(N, n): return int(((2 * N + n ** 2) ** 0.5 - 3 * n) / 2) + 1 def search(limit): count = 0 for n in range(1, range_n(limit)): for k in range(1, range_k(limit, n), 2): if number_theory.gcd(n, k) > 1: continue p = 2 * n ** 2 q = k ** 2 r = 2 * n * k if (p + q + r) % abs(p - q): continue print(n, k) count += limit // (2 * p + 2 * q + 3 * r) return count def perfect(limit): def side(n, k): return 4 * n ** 2 + 6 * n * k + 2 * k ** 2 def sqrt2(n): m = int(n * 2 ** 0.5) return m + (1 - m % 2) n, k = 1, 1 border = 12 count = 0 while border < limit: yield limit // border n = n + k k = sqrt2(n) border = side(n, k) #print(search(100000000)) print(sum(list(perfect(100000000))))