-
Notifications
You must be signed in to change notification settings - Fork 1
/
euler_583_v3.py
99 lines (82 loc) · 2.49 KB
/
euler_583_v3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import time
import math
import operator
def is_square(integer):
root = math.sqrt(integer)
test = int(root + 0.5)
if test ** 2 == integer:
return True
else:
return False
def gcd(a,b):
while a:
a, b = b%a, a
return b
def multi_gcd(*args):
return reduce(gcd,args)
#def max_v(N):
# return int(math.sqrt(5*N**2-38*N+73)/2.)
def max_m(n,N):
return min((N-3)/(4*n),int(math.sqrt(n**2+N-4)))
def max_n(N):
return (N-3)/8
def flap_height(x,z):
return math.sqrt(z**2 - (x/2.)**2)
def AC_diagonal_squared_times_4(x,y,h):
return x**2 + 4*(y+h)**2
def z_range(x,y):
z_min = x/2 + 1
z_max = int(math.sqrt(x**2+4*(y-1)**2)/2.)
return z_min, z_max
N = 10**3
start = time.time()
primitive_pythag_triples = []
n_max = max_n(N)
for n in xrange(1,n_max+1,2):
m_max = max_m(n,N)
for m in xrange(n+1,m_max+1,2):
if (gcd(m,n)!=1):
continue
mm, nn = m**2, n**2
primitive_pythag_triples.append((mm-nn, 2*m*n, mm+nn))
for n in xrange(2,n_max+1,2):
m_max = max_m(n,N)
for m in xrange(n+1,m_max+1,2):
if (gcd(m,n)!=1):
continue
mm, nn = m**2, n**2
primitive_pythag_triples.append((mm-nn, 2*m*n, mm+nn))
primitive_pythag_triples.sort(key=operator.itemgetter(2))
print primitive_pythag_triples
total = 0
how_often = 20
num_triples = len(primitive_pythag_triples)
status_when = num_triples/how_often
for j,triple in enumerate(primitive_pythag_triples):
if (j%status_when==0) and (j>0):
print j/status_when, "/", how_often
#print triple
for i in xrange(2):
primitive_x,primitive_y = triple[i],triple[1-i]
x,y = primitive_x,primitive_y
z_min, z_max = z_range(x,y)
for top_triple in primitive_pythag_triples:
original_2z = 2*top_triple[-1]
a = 0
while True:
a += 1
temp_2z = a*original_2z
if (temp_2z < 2*z_min):
continue
elif (2*z_min <= temp_2z <= 2*z_max):
#print top_triple
if (x in top_triple):
perim = x + 2*y + temp_2z
if (perim<=N):
total += perim
print (x, y, temp_2z)
else:
break
time_taken = time.time()-start
print "\n{}: {}".format(N,total)
print round(time_taken,1), "s\n"