44 lines
1.5 KiB
Text
44 lines
1.5 KiB
Text
with javascript_semantics
|
|
function count_triplets(atom max_perimeter)
|
|
integer limit = floor(sqrt(max_perimeter/2))+1
|
|
atom total = 0, primitive = 0, t0 = time(), t1 = t0+1
|
|
// The formulas below generate primitive triples if:
|
|
// 0 < n < m
|
|
// m and n are relatively prime (gcd == 1)
|
|
// m + n is odd
|
|
for m=2 to limit do
|
|
for n=1+odd(m) to m-1 by 2 do
|
|
-- if gcd(m,n)=1 then
|
|
-- inlined for a 5-fold speedup:
|
|
integer u = m, v = n, t
|
|
do
|
|
t = u
|
|
u = v
|
|
v = rmdr(t,v)
|
|
until v=0
|
|
if u=1 then
|
|
-- a = m*m - n*n
|
|
-- b = 2*m*n
|
|
-- c = m*m + n*n
|
|
-- perimeter = a + b + c
|
|
atom perimeter = 2*m*(m+n)
|
|
if perimeter <= max_perimeter then
|
|
primitive += 1
|
|
total += floor(max_perimeter/perimeter)
|
|
end if
|
|
end if
|
|
end for
|
|
if time()>t1 then
|
|
progress("m:%d/%d (%d%%)\r",{m,limit,m/limit*100})
|
|
t1 = time()+1
|
|
end if
|
|
end for
|
|
string e = elapsed_short(time()-t0,1," (%s)")
|
|
return {max_perimeter, total, primitive, e}
|
|
end function
|
|
|
|
integer limit = iff(platform()=JS?9:10)
|
|
for max_perimeter in sq_power(10,tagset(limit)) do
|
|
printf(1,"Up to %,d: %,d triples, %,d primitives%s.\n",
|
|
count_triplets(max_perimeter))
|
|
end for
|