A Pythagorean triple is defined as three positive integers 



(
a
,
b
,
c
)


{\displaystyle (a,b,c)}

 where 



a
<
b
<
c


{\displaystyle a<b<c}

, and 




a

2


+

b

2


=

c

2


.


{\displaystyle a^{2}+b^{2}=c^{2}.}



They are called primitive triples if 



a
,
b
,
c


{\displaystyle a,b,c}

 are co-prime, that is, if their pairwise greatest common divisors 





g
c
d


(
a
,
b
)
=


g
c
d


(
a
,
c
)
=


g
c
d


(
b
,
c
)
=
1


{\displaystyle {\rm {gcd}}(a,b)={\rm {gcd}}(a,c)={\rm {gcd}}(b,c)=1}

.

Because of their relationship through the Pythagorean theorem, a, b, and c are co-prime if a and b are co-prime (





g
c
d


(
a
,
b
)
=
1


{\displaystyle {\rm {gcd}}(a,b)=1}

).  

Each triple forms the length of the sides of a right triangle, whose perimeter is 



P
=
a
+
b
+
c


{\displaystyle P=a+b+c}

.



Task

The task is to determine how many Pythagorean triples there are with a perimeter no larger than 100 and the number of these that are primitive.



Extra credit
 
Deal with large values.   Can your program handle a maximum perimeter of 1,000,000?   What about 10,000,000?   100,000,000?

Note: the extra credit is not for you to demonstrate how fast your language is compared to others;   you need a proper algorithm to solve them in a timely manner.



Related tasks

   Euler's sum of powers conjecture 
   List comprehensions
   Pythagorean quadruples 


 
 
Procedure.i ConsoleWrite(t.s)  ; compile using /CONSOLE option
        OpenConsole()
        PrintN (t.s)
        CloseConsole()
        ProcedureReturn 1
EndProcedure
 
Procedure.i StdOut(t.s)  ; compile using /CONSOLE option
        OpenConsole()
        Print(t.s)
        CloseConsole()
        ProcedureReturn 1
EndProcedure
 
Procedure.i gcDiv(n,m) ; greatest common divisor
if n=0:ProcedureReturn m:endif
while m <> 0
  if n > m
    n - m
  else
    m - n
  endif
wend
ProcedureReturn n
EndProcedure
 
st=ElapsedMilliseconds()
 
nmax      =10000
power     =8
 
dim primitiveA(power)
dim alltripleA(power)
dim pmaxA(power)
 
x=1
for i=1 to power
  x*10:pmaxA(i)=x/2
next
 
for n=1 to nmax
  for m=(n+1) to (nmax+1) step 2 ; assure m-n is odd
    d=gcDiv(n,m)
    p=m*m+m*n
    for i=1 to power
      if p<=pmaxA(i)
        if d =1
        primitiveA(i)+1        ; right here we have the primitive perimeter "seed" 'p'
        k=1:q=p*k              ; set k to one to include p : use q as the 'p*k'
          while q<=pmaxA(i)
          alltripleA(i)+1      ; accumulate multiples of this perimeter while q <= pmaxA(i)
          k+1:q=p*k
          wend
        endif
      endif
    next
  next
next
 
for i=1 to power
  t.s="Up to "+str(pmaxA(i)*2)+": "
  t.s+str(alltripleA(i))+" triples, "
  t.s+str(primitiveA(i))+" primitives."
  ConsoleWrite(t.s)
next
ConsoleWrite("")
et=ElapsedMilliseconds()-st:ConsoleWrite("Elapsed time = "+str(et)+" milliseconds")
 