Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Pythagorean_triples

View file

@ -0,0 +1,25 @@
A [[wp:Pythagorean_triple|Pythagorean triple]] is defined as three positive integers <math>(a, b, c)</math> where <math>a < b < c</math>, and <math>a^2+b^2=c^2.</math>
They are called primitive triples if <math>a, b, c</math> are co-prime, that is, if their pairwise greatest common divisors <math>{\rm gcd}(a, b) = {\rm gcd}(a, c) = {\rm gcd}(b, c) = 1</math>.
Because of their relationship through the Pythagorean theorem, a, b, and c are co-prime if a and b are co-prime (<math>{\rm gcd}(a, b) = 1</math>). &nbsp;
Each triple forms the length of the sides of a right triangle, whose perimeter is <math>P=a+b+c</math>.
;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. &nbsp; Can your program handle a maximum perimeter of 1,000,000? &nbsp; What about 10,000,000? &nbsp; 100,000,000?
Note: the extra credit is not for you to demonstrate how fast your language is compared to others; &nbsp; you need a proper algorithm to solve them in a timely manner.
;Related tasks:
* &nbsp; [[Euler's sum of powers conjecture]]
* &nbsp; [[List comprehensions]]
* &nbsp; [[Pythagorean quadruples]]
<br><br>

View file

@ -0,0 +1,30 @@
Int64 nTriples, nPrimitives, limit
F countTriples(Int64 =x, =y, =z)
L
V p = x + y + z
I p > :limit
R
:nPrimitives++
:nTriples += :limit I/ p
V t0 = x - 2 * y + 2 * z
V t1 = 2 * x - y + 2 * z
V t2 = t1 - y + z
countTriples(t0, t1, t2)
t0 += 4 * y
t1 += 2 * y
t2 += 4 * y
countTriples(t0, t1, t2)
z = t2 - 4 * x
y = t1 - 4 * x
x = t0 - 2 * x
L(p) 1..8
limit = Int64(10) ^ p
nTriples = nPrimitives = 0
countTriples(3, 4, 5)
print(Up to #11: #11 triples, #9 primitives..format(limit, nTriples, nPrimitives))

View file

@ -0,0 +1,127 @@
* Pythagorean triples - 12/06/2018
PYTHTRI CSECT
USING PYTHTRI,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
SAVE (14,12) save previous context
ST R13,4(R15) link backward
ST R15,8(R13) link forward
LR R13,R15 set addressability
MVC PMAX,=F'1' pmax=1
LA R6,1 i=1
DO WHILE=(C,R6,LE,=F'6') do i=1 to 6
L R5,PMAX pmax
MH R5,=H'10' *10
ST R5,PMAX pmax=pmax*10
MVC PRIM,=F'0' prim=0
MVC COUNT,=F'0' count=0
L R1,PMAX pmax
BAL R14,ISQRT isqrt(pmax)
SRA R0,1 /2
ST R0,NMAX nmax=isqrt(pmax)/2
LA R7,1 n=1
DO WHILE=(C,R7,LE,NMAX) do n=1 to nmax
LA R9,1(R7) m=n+1
LR R5,R9 m
AR R5,R7 +n
MR R4,R9 *m
SLA R5,1 *2
LR R8,R5 p=2*m*(m+n)
DO WHILE=(C,R8,LE,PMAX) do while p<=pmax
LR R1,R9 m
LR R2,R7 n
BAL R14,GCD gcd(m,n)
IF C,R0,EQ,=F'1' THEN if gcd(m,n)=1 then
L R2,PRIM prim
LA R2,1(R2) +1
ST R2,PRIM prim=prim+1
L R4,PMAX pmax
SRDA R4,32 ~
DR R4,R8 /p
A R5,COUNT +count
ST R5,COUNT count=count+pmax/p
ENDIF , endif
LA R9,2(R9) m=m+2
LR R5,R9 m
AR R5,R7 +n
MR R4,R9 *m
SLA R5,1 *2
LR R8,R5 p=2*m*(m+n)
ENDDO , enddo n
LA R7,1(R7) n++
ENDDO , enddo n
L R1,PMAX pmax
XDECO R1,XDEC edit pmax
MVC PG+15(9),XDEC+3 output pmax
L R1,COUNT count
XDECO R1,XDEC edit count
MVC PG+33(9),XDEC+3 output count
L R1,PRIM prim
XDECO R1,XDEC edit prim
MVC PG+55(9),XDEC+3 output prim
XPRNT PG,L'PG print
LA R6,1(R6) i++
ENDDO , enddo i
L R13,4(0,R13) restore previous savearea pointer
RETURN (14,12),RC=0 restore registers from calling sav
NMAX DS F nmax
PMAX DS F pmax
COUNT DS F count
PRIM DS F prim
PG DC CL80'Max Perimeter: ........., Total: ........., Primitive:'
XDEC DS CL12
GCD EQU * --------------- function gcd(a,b)
STM R2,R7,GCDSA save context
LR R3,R1 c=a
LR R4,R2 d=b
GCDLOOP LR R6,R3 c
SRDA R6,32 ~
DR R6,R4 /d
LTR R6,R6 if c mod d=0
BZ GCDELOOP then leave loop
LR R5,R6 e=c mod d
LR R3,R4 c=d
LR R4,R5 d=e
B GCDLOOP loop
GCDELOOP LR R0,R4 return(d)
LM R2,R7,GCDSA restore context
BR R14 return
GCDSA DS 6A context store
ISQRT EQU * --------------- function isqrt(n)
STM R3,R10,ISQRTSA save context
LR R6,R1 n=r1
LR R10,R6 sqrtn=n
SRA R10,1 sqrtn=n/2
IF LTR,R10,Z,R10 THEN if sqrtn=0 then
LA R10,1 sqrtn=1
ELSE , else
LA R9,0 snm2=0
LA R8,0 snm1=0
LA R7,0 sn=0
LA R3,0 okexit=0
DO UNTIL=(C,R3,EQ,=A(1)) do until okexit=1
AR R10,R7 sqrtn=sqrtn+sn
LR R9,R8 snm2=snm1
LR R8,R7 snm1=sn
LR R4,R6 n
SRDA R4,32 ~
DR R4,R10 /sqrtn
SR R5,R10 -sqrtn
SRA R5,1 /2
LR R7,R5 sn=(n/sqrtn-sqrtn)/2
IF C,R7,EQ,=F'0',OR,CR,R7,EQ,R9 THEN if sn=0 or sn=snm2 then
LA R3,1 okexit=1
ENDIF , endif
ENDDO , enddo until
ENDIF , endif
LR R5,R10 sqrtn
MR R4,R10 *sqrtn
IF CR,R5,GT,R6 THEN if sqrtn*sqrtn>n then
BCTR R10,0 sqrtn=sqrtn-1
ENDIF , endif
LR R0,R10 return(sqrtn)
LM R3,R10,ISQRTSA restore context
BR R14 return
ISQRTSA DS 8A context store
YREGS
END PYTHTRI

View file

@ -0,0 +1,43 @@
100 DECLARE EXTERNAL SUB tri
110 !
120 PUBLIC NUMERIC U0(3,3), U1(3,3), U2(3,3), all, prim
130 DIM seed(3)
140 MAT READ U0, U1, U2
150 DATA 1, -2, 2, 2, -1, 2, 2, -2, 3
160 DATA 1, 2, 2, 2, 1, 2, 2, 2, 3
170 DATA -1, 2, 2, -2, 1, 2, -2, 2, 3
180 !
190 MAT READ seed
200 DATA 3, 4, 5
210 FOR power = 1 TO 7
220 LET all = 0
230 LET prim = 0
240 CALL tri(seed, 10^power , all , prim)
250 PRINT "Up to 10^";power,
260 PRINT USING "######### triples ######### primitives":all,prim
270 NEXT power
280 END
290 !
300 EXTERNAL SUB tri(i(), mp, all, prim)
310 DECLARE EXTERNAL FUNCTION SUM
320 DECLARE NUMERIC t(3)
330 !
340 IF SUM(i) > mp THEN EXIT SUB
350 LET prim = prim + 1
360 LET all = all + INT(mp / SUM(i))
370 !
380 MAT t = U0 * i
390 CALL tri(t, mp , all , prim)
400 MAT t = U1 * i
410 CALL tri(t, mp , all , prim)
420 MAT t = U2 * i
430 CALL tri(t, mp , all , prim)
440 END SUB
450 !
460 EXTERNAL FUNCTION SUM(a())
470 LET temp = 0
480 FOR i=LBOUND(a) TO UBOUND(a)
490 LET temp = temp + a(i)
500 NEXT i
510 LET SUM = temp
520 END FUNCTION

View file

@ -0,0 +1,32 @@
⍝ Determine whether given list of integers has GCD = 1
primitive/1=2/
⍝ Filter list given as right operand by applying predicate given as left operand
filter{ }
⍝ Function pytriples finds all triples given a maximum perimeter
respytriples maxperimeter;sos;sqrt;cartprod;ascending;ab_max;c_max;a_b_pairs;sos_is_sq;add_c;perimeter_rule
⍝ Input parameter maxperimeter is the maximum perimeter
⍝ Sum of squares of given list of nrs
sos+/(×)
⍝ Square root
sqrt(÷2)*
⍝ (cartesian product) all possible pairs of integers
⍝ from 1 to ⍵
cartprod{,{.,}}
⍝ Predicate: are values in given list ascending
⍝ Given e.g. pair a, b, c: is a ≤ b ≤ c?
ascending/2/
ab_maxmaxperimeter÷2
c_maxmaxperimeter×sqrt 2
⍝ Selects from all a,b combinations (a<abmax, b<abmax)
⍝ only those pairs where a ≤ b.
a_b_pairsascending filter¨cartprod(ab_max)
⍝ Predicate: is the sum of squares of a and b
⍝ itself a square? (does it occur in the squares list)
sos_is_sq{{1+c_max}(×c_max)sos¨}
⍝ Given a pair a,b add corresponding c to form a triple
add_c{,sqrt sos }
⍝ Predicate: sum of items less than or equal to max
perimeter_rule{maxperimeter+/}
resperimeter_rule¨filter add_c¨sos_is_sq filter a_b_pairs

View file

@ -0,0 +1,23 @@
# syntax: GAWK -f PYTHAGOREAN_TRIPLES.AWK
# converted from Go
BEGIN {
printf("%5s %11s %11s %11s %s\n","limit","limit","triples","primitives","seconds")
for (max_peri=10; max_peri<=1E9; max_peri*=10) {
t = systime()
prim = 0
total = 0
new_tri(3,4,5)
printf("10^%-2d %11d %11d %11d %d\n",++n,max_peri,total,prim,systime()-t)
}
exit(0)
}
function new_tri(s0,s1,s2, p) {
p = s0 + s1 + s2
if (p <= max_peri) {
prim++
total += int(max_peri / p)
new_tri(+1*s0-2*s1+2*s2,+2*s0-1*s1+2*s2,+2*s0-2*s1+3*s2)
new_tri(+1*s0+2*s1+2*s2,+2*s0+1*s1+2*s2,+2*s0+2*s1+3*s2)
new_tri(-1*s0+2*s1+2*s2,-2*s0+1*s1+2*s2,-2*s0+2*s1+3*s2)
}
}

View file

@ -0,0 +1,108 @@
DEFINE PTR="CARD"
DEFINE ENTRY_SIZE="3"
TYPE TRIPLE=[BYTE a,b,c]
TYPE TRIPLES=[
PTR buf ;BYTE ARRAY
BYTE count]
PTR FUNC GetItemAddr(TRIPLES POINTER arr BYTE index)
PTR addr
addr=arr.buf+index*ENTRY_SIZE
RETURN (addr)
PROC PrintTriples(TRIPLES POINTER arr)
INT i
TRIPLE POINTER t
FOR i=0 TO arr.count-1
DO
t=GetItemAddr(arr,i)
PrintF("(%B %B %B) ",t.a,t.b,t.c)
OD
RETURN
PROC Init(TRIPLES POINTER arr BYTE ARRAY b)
arr.buf=b
arr.count=0
RETURN
PROC AddItem(TRIPLES POINTER arr TRIPLE POINTER t)
TRIPLE POINTER p
p=GetItemAddr(arr,arr.count)
p.a=t.a
p.b=t.b
p.c=t.c
arr.count==+1
RETURN
PROC FindTriples(TRIPLES POINTER res BYTE limit)
BYTE ARRAY data(100)
BYTE half,i,j,k
TRIPLE t
Init(res,data)
half=limit/2
FOR i=1 TO half
DO
FOR j=i TO half
DO
FOR k=j TO limit
DO
IF i+j+k<limit AND i*i+j*j=k*k THEN
t.a=i t.b=j t.c=k
AddItem(res,t)
FI
OD
OD
OD
RETURN
BYTE FUNC Gcd(BYTE a,b)
BYTE tmp
IF a<b THEN
tmp=a a=b b=tmp
FI
WHILE b#0
DO
tmp=a MOD b
a=b b=tmp
OD
RETURN (a)
BYTE FUNC IsPrimitive(TRIPLE POINTER t)
IF Gcd(t.a,t.b)>1 THEN RETURN (0) FI
IF Gcd(t.b,t.c)>1 THEN RETURN (0) FI
IF Gcd(t.a,t.c)>1 THEN RETURN (0) FI
RETURN (1)
PROC FindPrimitives(TRIPLES POINTER arr,res)
BYTE ARRAY data(100)
INT i
TRIPLE POINTER t
Init(res,data)
FOR i=0 TO arr.count-1
DO
t=GetItemAddr(arr,i)
IF IsPrimitive(t) THEN
AddItem(res,t)
FI
OD
RETURN
PROC Main()
DEFINE LIMIT="100"
TRIPLES res,res2
FindTriples(res,LIMIT)
PrintF("There are %B pythagorean triples with a perimeter less than %B:%E%E",res.count,LIMIT)
PrintTriples(res)
FindPrimitives(res,res2)
PrintF("%E%E%E%B of them are primitive:%E%E",res2.count)
PrintTriples(res2)
RETURN

View file

@ -0,0 +1,33 @@
with Ada.Text_IO;
procedure Pythagorean_Triples is
type Large_Natural is range 0 .. 2**63-1;
-- this is the maximum for gnat
procedure New_Triangle(A, B, C: Large_Natural;
Max_Perimeter: Large_Natural;
Total_Cnt, Primitive_Cnt: in out Large_Natural) is
Perimeter: constant Large_Natural := A + B + C;
begin
if Perimeter <= Max_Perimeter then
Primitive_Cnt := Primitive_Cnt + 1;
Total_Cnt := Total_Cnt + Max_Perimeter / Perimeter;
New_Triangle(A-2*B+2*C, 2*A-B+2*C, 2*A-2*B+3*C, Max_Perimeter, Total_Cnt, Primitive_Cnt);
New_Triangle(A+2*B+2*C, 2*A+B+2*C, 2*A+2*B+3*C, Max_Perimeter, Total_Cnt, Primitive_Cnt);
New_Triangle(2*B+2*C-A, B+2*C-2*A, 2*B+3*C-2*A, Max_Perimeter, Total_Cnt, Primitive_Cnt);
end if;
end New_Triangle;
T_Cnt, P_Cnt: Large_Natural;
begin
for I in 1 .. 9 loop
T_Cnt := 0;
P_Cnt := 0;
New_Triangle(3,4,5, 10**I, Total_Cnt => T_Cnt, Primitive_Cnt => P_Cnt);
Ada.Text_IO.Put_Line("Up to 10 **" & Integer'Image(I) & " :" &
Large_Natural'Image(T_Cnt) & " Triples," &
Large_Natural'Image(P_Cnt) & " Primitives");
end loop;
end Pythagorean_Triples;

View file

@ -0,0 +1,21 @@
triples: new []
loop 1..50 'x [
loop 1..50 'y [
loop (max @[x y])..100 'z [
if 100 > sum @[x y z] [
if (z^2) = add x^2 y^2 ->
'triples ++ @[sort @[x y z]]
]
]
]
]
unique 'triples
print ["Found" size triples "pythagorean triples with a perimeter no larger than 100:"]
print triples
primitive: select triples => [1 = gcd]
print ""
print [size primitive "of them are primitive:"]
print primitive

View file

@ -0,0 +1,30 @@
#NoEnv
SetBatchLines, -1
#SingleInstance, Force
; Greatest common divisor, from http://rosettacode.org/wiki/Greatest_common_divisor#AutoHotkey
gcd(a,b) {
Return b=0 ? Abs(a) : Gcd(b,mod(a,b))
}
count_triples(max) {
primitives := 0, triples := 0, m := 2
while m <= (max / 2)**0.5
{
n := mod(m, 2) + 1
,p := 2*m*(m + n)
, delta := 4*m
while n < m and p <= max
gcd(m, n) = 1
? (primitives++
, triples += max // p)
: ""
, n += 2
, p += delta
m++
}
Return primitives " primitives out of " triples " triples"
}
Loop, 8
Msgbox % 10**A_Index ": " count_triples(10**A_Index)

View file

@ -0,0 +1,27 @@
DIM U0%(2,2), U1%(2,2), U2%(2,2), seed%(2)
U0%() = 1, -2, 2, 2, -1, 2, 2, -2, 3
U1%() = 1, 2, 2, 2, 1, 2, 2, 2, 3
U2%() = -1, 2, 2, -2, 1, 2, -2, 2, 3
seed%() = 3, 4, 5
FOR power% = 1 TO 7
all% = 0 : prim% = 0
PROCtri(seed%(), 10^power%, all%, prim%)
PRINT "Up to 10^"; power%, ": " all% " triples" prim% " primitives"
NEXT
END
DEF PROCtri(i%(), mp%, RETURN all%, RETURN prim%)
LOCAL t%() : DIM t%(2)
IF SUM(i%()) > mp% ENDPROC
prim% += 1
all% += mp% DIV SUM(i%())
t%() = U0%() . i%()
PROCtri(t%(), mp%, all%, prim%)
t%() = U1%() . i%()
PROCtri(t%(), mp%, all%, prim%)
t%() = U2%() . i%()
PROCtri(t%(), mp%, all%, prim%)
ENDPROC

View file

@ -0,0 +1,53 @@
(pythagoreanTriples=
total prim max-peri U
. (.(1,-2,2) (2,-1,2) (2,-2,3))
(.(1,2,2) (2,1,2) (2,2,3))
(.(-1,2,2) (-2,1,2) (-2,2,3))
: ?U
& ( new-tri
= i t p Urows Urow Ucols
, a b c loop A B C
. !arg:(,?a,?b,?c)
& !a+!b+!c:~>!max-peri:?p
& 1+!prim:?prim
& div$(!max-peri.!p)+!total:?total
& !U:?Urows
& ( loop
= !Urows:(.?Urow) ?Urows
& !Urow:?Ucols
& :?t
& whl
' ( !Ucols:(?A,?B,?C) ?Ucols
& (!t,!a*!A+!b*!B+!c*!C):?t
)
& new-tri$!t
& !loop
)
& !loop
|
)
& ( Main
= seed
. (,3,4,5):?seed
& 10:?max-peri
& whl
' ( 0:?total:?prim
& new-tri$!seed
& out
$ ( str
$ ( "Up to "
!max-peri
": "
!total
" triples, "
!prim
" primitives."
)
)
& !max-peri*10:~>10000000:?max-peri
)
)
& Main$
);
pythagoreanTriples$;

View file

@ -0,0 +1,54 @@
(pythagoreanTriples=
total prim max-peri U stack
. (.(1,-2,2) (2,-1,2) (2,-2,3))
(.(1,2,2) (2,1,2) (2,2,3))
(.(-1,2,2) (-2,1,2) (-2,2,3))
: ?U
& ( new-tri
= i t p Urows Urow Ucols Ucol
, a b c loop A B C
. !arg:(,?a,?b,?c)
& !a+!b+!c:~>!max-peri:?p
& 1+!prim:?prim
& div$(!max-peri.!p)+!total:?total
& !U:?Urows
& ( loop
= !Urows:(.?Urow) ?Urows
& !Urow:?Ucols
& :?t
& whl
' ( !Ucols:(?A,?B,?C) ?Ucols
& (!t,!a*!A+!b*!B+!c*!C):?t
)
& !t !stack:?stack
& !loop
)
& !loop
|
)
& ( Main
= seed
. 10:?max-peri
& whl
' ( 0:?total:?prim
& (,3,4,5):?stack
& whl
' (!stack:%?seed ?stack&new-tri$!seed)
& out
$ ( str
$ ( "Up to "
!max-peri
": "
!total
" triples, "
!prim
" primitives."
)
)
& !max-peri*10:~>100000000:?max-peri
)
)
& Main$
);
pythagoreanTriples$;

View file

@ -0,0 +1,54 @@
#include <cmath>
#include <iostream>
#include <numeric>
#include <tuple>
#include <vector>
using namespace std;
auto CountTriplets(unsigned long long maxPerimeter)
{
unsigned long long totalCount = 0;
unsigned long long primitveCount = 0;
auto max_M = (unsigned long long)sqrt(maxPerimeter/2) + 1;
for(unsigned long long m = 2; m < max_M; ++m)
{
for(unsigned long long n = 1 + m % 2; n < m; n+=2)
{
if(gcd(m,n) != 1)
{
continue;
}
// The formulas below will generate primitive triples if:
// 0 < n < m
// m and n are relatively prime (gcd == 1)
// m + n is odd
auto a = m * m - n * n;
auto b = 2 * m * n;
auto c = m * m + n * n;
auto perimeter = a + b + c;
if(perimeter <= maxPerimeter)
{
primitveCount++;
totalCount+= maxPerimeter / perimeter;
}
}
}
return tuple(totalCount, primitveCount);
}
int main()
{
vector<unsigned long long> inputs{100, 1000, 10'000, 100'000,
1000'000, 10'000'000, 100'000'000, 1000'000'000,
10'000'000'000}; // This last one takes almost a minute
for(auto maxPerimeter : inputs)
{
auto [total, primitive] = CountTriplets(maxPerimeter);
cout << "\nMax Perimeter: " << maxPerimeter << ", Total: " << total << ", Primitive: " << primitive ;
}
}

View file

@ -0,0 +1,40 @@
using System;
namespace RosettaCode.CSharp
{
class Program
{
static void Count_New_Triangle(ulong A, ulong B, ulong C, ulong Max_Perimeter, ref ulong Total_Cnt, ref ulong Primitive_Cnt)
{
ulong Perimeter = A + B + C;
if (Perimeter <= Max_Perimeter)
{
Primitive_Cnt = Primitive_Cnt + 1;
Total_Cnt = Total_Cnt + Max_Perimeter / Perimeter;
Count_New_Triangle(A + 2 * C - 2 * B, 2 * A + 2 * C - B, 2 * A + 3 * C - 2 * B, Max_Perimeter, ref Total_Cnt, ref Primitive_Cnt);
Count_New_Triangle(A + 2 * B + 2 * C, 2 * A + B + 2 * C, 2 * A + 2 * B + 3 * C, Max_Perimeter, ref Total_Cnt, ref Primitive_Cnt);
Count_New_Triangle(2 * B + 2 * C - A, B + 2 * C - 2 * A, 2 * B + 3 * C - 2 * A, Max_Perimeter, ref Total_Cnt, ref Primitive_Cnt);
}
}
static void Count_Pythagorean_Triples()
{
ulong T_Cnt, P_Cnt;
for (int I = 1; I <= 8; I++)
{
T_Cnt = 0;
P_Cnt = 0;
ulong ExponentNumberValue = (ulong)Math.Pow(10, I);
Count_New_Triangle(3, 4, 5, ExponentNumberValue, ref T_Cnt, ref P_Cnt);
Console.WriteLine("Perimeter up to 10E" + I + " : " + T_Cnt + " Triples, " + P_Cnt + " Primitives");
}
}
static void Main(string[] args)
{
Count_Pythagorean_Triples();
}
}
}

View file

@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long xint;
typedef unsigned long ulong;
inline ulong gcd(ulong m, ulong n)
{
ulong t;
while (n) { t = n; n = m % n; m = t; }
return m;
}
int main()
{
ulong a, b, c, pytha = 0, prim = 0, max_p = 100;
xint aa, bb, cc;
for (a = 1; a <= max_p / 3; a++) {
aa = (xint)a * a;
printf("a = %lu\r", a); /* show that we are working */
fflush(stdout);
/* max_p/2: valid limit, because one side of triangle
* must be less than the sum of the other two
*/
for (b = a + 1; b < max_p/2; b++) {
bb = (xint)b * b;
for (c = b + 1; c < max_p/2; c++) {
cc = (xint)c * c;
if (aa + bb < cc) break;
if (a + b + c > max_p) break;
if (aa + bb == cc) {
pytha++;
if (gcd(a, b) == 1) prim++;
}
}
}
}
printf("Up to %lu, there are %lu triples, of which %lu are primitive\n",
max_p, pytha, prim);
return 0;
}

View file

@ -0,0 +1 @@
Up to 100, there are 17 triples, of which 7 are primitive

View file

@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/* should be 64-bit integers if going over 1 billion */
typedef unsigned long xint;
#define FMT "%lu"
xint total, prim, max_peri;
xint U[][9] = {{ 1, -2, 2, 2, -1, 2, 2, -2, 3},
{ 1, 2, 2, 2, 1, 2, 2, 2, 3},
{-1, 2, 2, -2, 1, 2, -2, 2, 3}};
void new_tri(xint in[])
{
int i;
xint t[3], p = in[0] + in[1] + in[2];
if (p > max_peri) return;
prim ++;
/* for every primitive triangle, its multiples would be right-angled too;
* count them up to the max perimeter */
total += max_peri / p;
/* recursively produce next tier by multiplying the matrices */
for (i = 0; i < 3; i++) {
t[0] = U[i][0] * in[0] + U[i][1] * in[1] + U[i][2] * in[2];
t[1] = U[i][3] * in[0] + U[i][4] * in[1] + U[i][5] * in[2];
t[2] = U[i][6] * in[0] + U[i][7] * in[1] + U[i][8] * in[2];
new_tri(t);
}
}
int main()
{
xint seed[3] = {3, 4, 5};
for (max_peri = 10; max_peri <= 100000000; max_peri *= 10) {
total = prim = 0;
new_tri(seed);
printf( "Up to "FMT": "FMT" triples, "FMT" primitives.\n",
max_peri, total, prim);
}
return 0;
}

View file

@ -0,0 +1,8 @@
Up to 10: 0 triples, 0 primitives.
Up to 100: 17 triples, 7 primitives.
Up to 1000: 325 triples, 70 primitives.
Up to 10000: 4858 triples, 703 primitives.
Up to 100000: 64741 triples, 7026 primitives.
Up to 1000000: 808950 triples, 70229 primitives.
Up to 10000000: 9706567 triples, 702309 primitives.
Up to 100000000: 113236940 triples, 7023027 primitives.

View file

@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/* should be 64-bit integers if going over 1 billion */
typedef unsigned long xint;
#define FMT "%lu"
xint total, prim, max_peri;
void new_tri(xint in[])
{
int i;
xint t[3], p;
xint x = in[0], y = in[1], z = in[2];
recur: p = x + y + z;
if (p > max_peri) return;
prim ++;
total += max_peri / p;
t[0] = x - 2 * y + 2 * z;
t[1] = 2 * x - y + 2 * z;
t[2] = t[1] - y + z;
new_tri(t);
t[0] += 4 * y;
t[1] += 2 * y;
t[2] += 4 * y;
new_tri(t);
z = t[2] - 4 * x;
y = t[1] - 4 * x;
x = t[0] - 2 * x;
goto recur;
}
int main()
{
xint seed[3] = {3, 4, 5};
for (max_peri = 10; max_peri <= 100000000; max_peri *= 10) {
total = prim = 0;
new_tri(seed);
printf( "Up to "FMT": "FMT" triples, "FMT" primitives.\n",
max_peri, total, prim);
}
return 0;
}

View file

@ -0,0 +1,17 @@
(defn gcd [a b] (if (zero? b) a (recur b (mod a b))))
(defn pyth [peri]
(for [m (range 2 (Math/sqrt (/ peri 2)))
n (range (inc (mod m 2)) m 2) ; n<m, opposite polarity
:let [p (* 2 m (+ m n))] ; = a+b+c for this (m,n)
:while (<= p peri)
:when (= 1 (gcd m n))
:let [m2 (* m m), n2 (* n n),
[a b] (sort [(- m2 n2) (* 2 m n)]), c (+ m2 n2)]
k (range 1 (inc (quot peri p)))]
[(= k 1) (* k a) (* k b) (* k c)]))
(defn rcount [ts] ; (->> peri pyth rcount) produces [total, primitive] counts
(reduce (fn [[total prims] t] [(inc total), (if (first t) (inc prims) prims)])
[0 0]
ts))

View file

@ -0,0 +1,8 @@
(defn pyth-count [peri]
(reduce (fn [[total prims] k] [(+ total k), (inc prims)]) [0 0]
(for [m (range 2 (Math/sqrt (/ peri 2)))
n (range (inc (mod m 2)) m 2) ; n<m, opposite polarity
:let [p (* 2 m (+ m n))] ; = a+b+c for this (m,n)
:while (<= p peri)
:when (= 1 (gcd m n))]
(quot peri p))))

View file

@ -0,0 +1,33 @@
gcd = (x, y) ->
return x if y == 0
gcd(y, x % y)
# m,n generate primitive Pythag triples
#
# preconditions:
# m, n are integers of different parity
# m > n
# gcd(m,n) == 1 (coprime)
#
# m, n generate: [m*m - n*n, 2*m*n, m*m + n*n]
# perimeter is 2*m*m + 2*m*n = 2 * m * (m+n)
count_triples = (max_perim) ->
num_primitives = 0
num_triples = 0
m = 2
upper_limit = Math.sqrt max_perim / 2
while m <= upper_limit
n = m % 2 + 1
p = 2*m*m + 2*m*n
delta = 4*m
while n < m and p <= max_perim
if gcd(m, n) == 1
num_primitives += 1
num_triples += Math.floor max_perim / p
n += 2
p += delta
m += 1
console.log num_primitives, num_triples
max_perim = Math.pow 10, 9 # takes under a minute
count_triples(max_perim)

View file

@ -0,0 +1,17 @@
(defun mmul (a b)
(loop for x in a collect
(loop for y in x
for z in b sum (* y z))))
(defun count-tri (lim &aux (prim 0) (cnt 0))
(labels ((count1 (tr &aux (peri (reduce #'+ tr)))
(when (<= peri lim)
(incf prim)
(incf cnt (truncate lim peri))
(count1 (mmul '(( 1 -2 2) ( 2 -1 2) ( 2 -2 3)) tr))
(count1 (mmul '(( 1 2 2) ( 2 1 2) ( 2 2 3)) tr))
(count1 (mmul '((-1 2 2) (-2 1 2) (-2 2 3)) tr)))))
(count1 '(3 4 5))
(format t "~a: ~a prim, ~a all~%" lim prim cnt)))
(loop for p from 2 do (count-tri (expt 10 p)))

View file

@ -0,0 +1,7 @@
100: 7 prim, 17 all
1000: 70 prim, 325 all
10000: 703 prim, 4858 all
100000: 7026 prim, 64741 all
1000000: 70229 prim, 808950 all
10000000: 702309 prim, 9706567 all
...

View file

@ -0,0 +1,30 @@
class PythagoranTriplesCounter
def initialize(limit = 0)
@limit = limit
@total = 0
@primitives = 0
generate_triples(3, 4, 5)
end
def total; @total end
def primitives; @primitives end
private def generate_triples(a, b, c)
perim = a + b + c
return if perim > @limit
@primitives += 1
@total += @limit // perim
generate_triples( a-2*b+2*c, 2*a-b+2*c, 2*a-2*b+3*c )
generate_triples( a+2*b+2*c, 2*a+b+2*c, 2*a+2*b+3*c )
generate_triples(-a+2*b+2*c,-2*a+b+2*c,-2*a+2*b+3*c )
end
end
perim = 10
while perim <= 100_000_000
c = PythagoranTriplesCounter.new perim
p [perim, c.total, c.primitives]
perim *= 10
end

View file

@ -0,0 +1,15 @@
void main() @safe {
import std.stdio, std.range, std.algorithm, std.typecons, std.numeric;
enum triples = (in uint n) pure nothrow @safe /*@nogc*/ =>
iota(1, n + 1)
.map!(z => iota(1, z + 1)
.map!(x => iota(x, z + 1).map!(y => tuple(x, y, z))))
.joiner.joiner
.filter!(t => t[0] ^^ 2 + t[1] ^^ 2 == t[2] ^^ 2 && t[].only.sum <= n)
.map!(t => tuple(t[0 .. 2].gcd == 1, t[]));
auto xs = triples(100);
writeln("Up to 100 there are ", xs.count, " triples, ",
xs.filter!q{ a[0] }.count, " are primitive.");
}

View file

@ -0,0 +1,17 @@
ulong[2] tri(ulong lim, ulong a=3, ulong b=4, ulong c=5)
pure nothrow @safe @nogc {
immutable l = a + b + c;
if (l > lim)
return [0, 0];
typeof(return) r = [1, lim / l];
r[] += tri(lim, a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c)[];
r[] += tri(lim, a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c)[];
r[] += tri(lim, -a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c)[];
return r;
}
void main() /*@safe*/ {
import std.stdio;
foreach (immutable p; 1 .. 9)
writeln(10 ^^ p, ' ', tri(10 ^^ p));
}

View file

@ -0,0 +1,18 @@
import std.stdio, core.simd;
ulong2 tri(in ulong lim, in ulong a=3, in ulong b=4, in ulong c=5)
pure nothrow @safe @nogc {
immutable l = a + b + c;
if (l > lim)
return [0, 0];
typeof(return) r = [1, lim / l];
r += tri(lim, a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c);
r += tri(lim, a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c);
r += tri(lim, -a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c);
return r;
}
void main() /*@safe*/ {
foreach (immutable p; 1 .. 9)
writeln(10 ^^ p, ' ', tri(10 ^^ p).array);
}

View file

@ -0,0 +1,40 @@
import std.stdio;
alias Xuint = uint; // ulong if going over 1 billion.
__gshared Xuint nTriples, nPrimitives, limit;
void countTriples(Xuint x, Xuint y, Xuint z) nothrow @nogc {
while (true) {
immutable p = x + y + z;
if (p > limit)
return;
nPrimitives++;
nTriples += limit / p;
auto t0 = x - 2 * y + 2 * z;
auto t1 = 2 * x - y + 2 * z;
auto t2 = t1 - y + z;
countTriples(t0, t1, t2);
t0 += 4 * y;
t1 += 2 * y;
t2 += 4 * y;
countTriples(t0, t1, t2);
z = t2 - 4 * x;
y = t1 - 4 * x;
x = t0 - 2 * x;
}
}
void main() {
foreach (immutable p; 1 .. 9) {
limit = Xuint(10) ^^ p;
nTriples = nPrimitives = 0;
countTriples(3, 4, 5);
writefln("Up to %11d: %11d triples, %9d primitives.",
limit, nTriples, nPrimitives);
}
}

View file

@ -0,0 +1,213 @@
[Pythagorean triples for Rosetta code.
Counts (1) all Pythagorean triples (2) primitive Pythagorean triples,
with perimeter not greater than a given value.
Library subroutine M3, Prints header and is then overwritten.
Here, the last character sets the teleprinter to figures.]
..PZ [simulate blank tape]
PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF
@&*!MAX!PERIM!!!!!TOTAL!!!!!!PRIM@&#.
..PZ
[Library subroutine P7, prints long strictly positive integer;
10 characters, right justified, padded left with spaces.
Closed, even; 35 storage locations; working position 4D.]
T 56 K
GKA3FT26@H28#@NDYFLDT4DS27@TFH8@S8@T1FV4DAFG31@SFLDUFOFFFSFL4F
T4DA1FA27@G11@XFT28#ZPFT27ZP1024FP610D@524D!FO30@SFL8FE22@
[Subroutine for positive integer division.
Input: 4D = dividend, 6D = divisor.
Output: 4D = remainder, 6D = quotient.
37 locations; working locations 0D, 8D.]
T 100 K
GKA3FT35@A6DU8DTDA4DRDSDG13@T36@ADLDE4@T36@T6DA4DSDG23@
T4DA6DYFYFT6DT36@A8DSDE35@T36@ADRDTDA6DLDT6DE15@EFPF
[Subroutine to return GCD of two non-negative 35-bit integers.
Input: Integers at 4D, 6D.
Output: GCD at 4D; changes 6D.
41 locations; working location 0D.]
T 200 K
GKA3FT39@S4DE37@T40@A4DTDA6DRDSDG15@T40@ADLDE6@T40@A6DSDG20@T6D
T40@A4DSDE29@T40@ADRDTDE16@S6DE39@TDA4DT6DSDT4DE5@A6DT4DEFPF
[************************ ROSETTA CODE TASK *************************
Subroutine to count Pythagorean triples with given maximum perimeter.
Input: 0D = maximum perimeter.
Output: 4D = number of triples, 6D = number of primitive.
0D is changed.
Must be loaded at an even address.
Uses the well-known fact that a primitive Pythagorean triple is of the form
(m^2 - n^2, 2*m*n, m^2 + n^2) where m, n are coprime and of opposite parity.]
T 300 K
G K
A 3 F [make link]
E 16 @ [jump over variables and constants]
[Double values are put here to ensure even address]
[Variables]
[2] P F P F [maximum perimeter]
[4] P F P F [total number of Pythagorean triples]
[6] P F P F [number of primitive Pythagorean triples]
[8] P F P F [m]
[10] P F P F [n]
[Constants]
T12#Z PF T12Z [clears sandwich digit between 12 and 13]
[12] P D P F [double-value 1]
T14#Z PF T14Z [clears sandwich digit between 14 and 15]
[14] P1F P F [double-value 2]
[Continue with code]
[16] T 69 @ [plant link for return]
A D [load maximum perimeter]
T 2#@ [store locally]
T 4#@ [initialize counts of triangles to 0]
T 6#@
A 12#@ [load 1]
T 8#@ [m := 1]
[Next m, inc by 1]
[23] T F [clear acc]
A 8#@ [load m]
A 12#@ [add 1]
T 8#@ [update m]
H 8#@ [mult reg := m]
C 12#@ [acc := m AND 1]
A 12#@ [add 1]
T 10#@ [n := 1 if m even, 2 if m odd]
[Here to count triangles arising from m, n.
It's assumed m and n are known coprime.]
[31] A 31 @ [call the count subroutine,]
G 70 @ [result is in 6D]
S 6 D [load negative count]
G 40 @ [jump if count > 0]
[No triangles found for this n.
If n = 1 or 2 then whole thing is finished.
Else move on to next m.]
T F [clear acc]
A 14#@ [load 2]
S 10#@ [2 - n]
G 23 @ [if n > 2, go to next m]
E 64 @ [if n <= 2, exit]
[Found triangles, count is in 6D]
[40] T F [clear acc]
A 4#@ [load total count]
A 6 D [add count just found]
T 4#@ [update total count]
A 6#@ [load primitive count]
A 12#@ [add 1]
T 6#@ [update primitive count]
[47] T F [clear acc]
A 10#@ [load n]
A 14#@ [add 2]
U 10#@ [update n]
S 8#@ [is n > m?]
E 23 @ [if so, loop back for next m]
[Test whether m and n are coprime.]
T F [clear acc]
A 8#@ [load m]
T 4 D [to 4D for GCD routine]
A 10#@ [load n]
T 6 D [to 6D for GCD routine]
A 58 @ [call GCD routine,]
G 200 F [GCD is returned in 4D]
A 4 D [load GCD]
S 14#@ [is GCD = 1? (test by subtracting 2)]
E 47 @ [no, go straight to next n]
G 31 @ [yes, count triangles, then next n]
[64] T F [exit, clear acc]
A 4#@ [load total number of triples]
T 4 D [return in 4D]
A 6#@ [load number of primitive triples]
T 6 D [return in 6D]
[69] E F
[2nd-level subroutine to count triangles arising from m, n.
Assumes m, n are coprime and of opposite parity,
and m is in the multiplier register.
Result is returned in 6D.]
[70] A 3 F [make and plant link for return]
T 91 @
A 2#@ [acc := maximum perimeter]
T 4 D [to 4D for division routine]
A 8#@ [load m]
A 10#@ [add n]
T D [m + n to 0D]
V D [acc := m*(m + n)]
[Need to shift product 34 left to restore integer scaling.
Since we want 2*m*(m+n), shift 35 left.]
L F [13 left (maximum possible)]
L F [13 more]
L 128 F [9 more]
T 6 D [perimeter to 6D for division routine]
A 4 D [load maximum perimeter]
S 6 D [is perimeter > maximum?]
G 89 @ [quick exit if so]
T F [clear acc]
A 86 @ [call division routine,]
G 100 F [leaves count in 6D]
E 91 @ [jump to exit]
[89] T F [acc := 0]
T 6 D [return count = 0]
[91] E F
[Main routine. Load at an even address.]
T 500 K
G K
[The initial maximum perimeter is repeatedly multiplied by 10]
T#Z PF TZ [clears sandwich digit between 0 and 1]
[0] P50F PF [initial maximum perimeter <---------- EDIT HERE]
[2] P 3 F [number of values to calculate <---------- EDIT HERE]
[3] P D [1]
[4] P F P F [maximum perimeter]
[6] P F P F [total number of triples]
[8] P F P F [number of primitive triples]
[10] P F [negative count of values]
[11] # F [figures shift]
[12] @ F [carriage return]
[13] & F [line feed]
[14] K 4096 F [null char]
[Enter with acc = 0]
[15] S 2 @ [initialize a negative counter]
T 10 @ [(standard EDSAC practice)]
A #@ [initialize maximum perimeter]
T 4#@
[19] T F [clear acc]
A 4#@ [load maximum perimeter]
T D [to 0D for subroutine]
A 22 @ [call subroutine to count triples]
G 300 F
A 4 D [returns total number in 4D]
T 6#@ [save locally]
A 6 D [returns number of primitive in 6D]
T 8#@ [save locally]
[Print the result]
A 4#@ [load maximum perimeter]
T D [to 0D for print subroutine]
A 30 @ [call print subroutine]
G 56 F
A 6#@ [repeat for total number of triples]
T D
A 34 @
G 56 F
A 8#@ [repeat for number of primitive triples]
T D
A 38 @
G 56 F
O 12 @
O 13 @
A 10 @ [load negative count]
A 3 @ [add 1]
E 53 @ [out if reached 0]
T 10 @ [else update count]
A 4#@ [load max perimeter]
U D [temp store]
L 1 F [times 4]
A D [times 5]
L D [times 10]
T 4#@ [update]
E 19 @ [loop back]
[53] O 14 @ [done; print null to flush printer buffer]
Z F [stop]
E 15 Z [define entry point]
P F [acc = 0 on entry]

View file

@ -0,0 +1,59 @@
PROGRAM PIT
BEGIN
PRINT(CHR$(12);) !CLS
PRINT(TIME$)
FOR POWER=1 TO 7 DO
PLIMIT=10#^POWER
UPPERBOUND=INT(1+PLIMIT^0.5)
PRIMITIVES=0
TRIPLES=0
EXTRAS=0 ! will count the in-range multiples of any primitive
FOR M=2 TO UPPERBOUND DO
FOR N=1+(M MOD 2=1) TO M-1 STEP 2 DO
TERM1=2*M*N
TERM2=M*M-N*N
TERM3=M*M+N*N
PERIMETER=TERM1+TERM2+TERM3
IF PERIMETER<=PLIMIT THEN TRIPLES=TRIPLES+1
A=TERM1
B=TERM2
REPEAT
R=A-B*INT(A/B)
A=B
B=R
UNTIL R<=0
! we've found a primitive triple if a = 1, since hcf =1.
! and it is inside perimeter range. Save it in an array
IF (A=1) AND (PERIMETER<=PLIMIT) THEN
PRIMITIVES=PRIMITIVES+1
!-----------------------------------------------
!swap so in increasing order of side length
!-----------------------------------------------
IF TERM1>TERM2 THEN SWAP(TERM1,TERM2)
!-----------------------------------------------
!we have the primitive & removed any multiples.
!Now calculate ALL the multiples in range.
!-----------------------------------------------
NEX=INT(PLIMIT/PERIMETER)
EXTRAS=EXTRAS+NEX
END IF
!scan
END FOR
END FOR
PRINT("Primit. with perimeter <=";10#^power;"is";primitives;"&";extras;"non-prim.triples.")
PRINT(TIME$)
END FOR
PRINT PRINT("** End **")
END PROGRAM

View file

@ -0,0 +1,47 @@
class
APPLICATION
create
make
feature
make
local
perimeter: INTEGER
do
perimeter := 100
from
until
perimeter > 1000000
loop
total := 0
primitive_triples := 0
count_pythagorean_triples (3, 4, 5, perimeter)
io.put_string ("There are " + total.out + " triples, below " + perimeter.out + ". Of which " + primitive_triples.out + " are primitives.%N")
perimeter := perimeter * 10
end
end
count_pythagorean_triples (a, b, c, perimeter: INTEGER)
-- Total count of pythagorean triples and total count of primitve triples below perimeter.
local
p: INTEGER
do
p := a + b + c
if p <= perimeter then
primitive_triples := primitive_triples + 1
total := total + perimeter // p
count_pythagorean_triples (a + 2 * (- b + c), 2 * (a + c) - b, 2 * (a - b + c) + c, perimeter)
count_pythagorean_triples (a + 2 * (b + c), 2 * (a + c) + b, 2 * (a + b + c) + c, perimeter)
count_pythagorean_triples (- a + 2 * (b + c), 2 * (- a + c) + b, 2 * (- a + b + c) + c, perimeter)
end
end
feature {NONE}
primitive_triples: INTEGER
total: INTEGER
end

View file

@ -0,0 +1,14 @@
defmodule RC do
def count_triples(limit), do: count_triples(limit,3,4,5)
defp count_triples(limit, a, b, c) when limit<(a+b+c), do: {0,0}
defp count_triples(limit, a, b, c) do
{p1, t1} = count_triples(limit, a-2*b+2*c, 2*a-b+2*c, 2*a-2*b+3*c)
{p2, t2} = count_triples(limit, a+2*b+2*c, 2*a+b+2*c, 2*a+2*b+3*c)
{p3, t3} = count_triples(limit,-a+2*b+2*c,-2*a+b+2*c,-2*a+2*b+3*c)
{1+p1+p2+p3, div(limit, a+b+c)+t1+t2+t3}
end
end
list = for n <- 1..8, do: Enum.reduce(1..n, 1, fn(_,acc)->10*acc end)
Enum.each(list, fn n -> IO.inspect {n, RC.count_triples(n)} end)

View file

@ -0,0 +1,45 @@
%%
%% Pythagorian triples in Erlang, J.W. Luiten
%%
-module(triples).
-export([main/1]).
%% Transformations t1, t2 and t3 to generate new triples
t1(A, B, C) ->
{A-2*B+2*C, 2*A-B+2*C, 2*A-2*B+3*C}.
t2(A, B, C) ->
{A+2*B+2*C, 2*A+B+2*C, 2*A+2*B+3*C}.
t3(A, B, C) ->
{2*B+2*C-A, B+2*C-2*A, 2*B+3*C-2*A}.
%% Generation of triples
count_triples(A, B, C, Tot_acc, Cnt_acc, Max_perimeter) when (A+B+C) =< Max_perimeter ->
Tot1 = Tot_acc + Max_perimeter div (A+B+C),
{A1, B1, C1} = t1(A, B, C),
{Tot2, Cnt2} = count_triples(A1, B1, C1, Tot1, Cnt_acc+1, Max_perimeter),
{A2, B2, C2} = t2(A, B, C),
{Tot3, Cnt3} = count_triples(A2, B2, C2, Tot2, Cnt2, Max_perimeter),
{A3, B3, C3} = t3(A, B, C),
{Tot4, Cnt4} = count_triples(A3, B3, C3, Tot3, Cnt3, Max_perimeter),
{Tot4, Cnt4};
count_triples(_A, _B, _C, Tot_acc, Cnt_acc, _Max_perimeter) ->
{Tot_acc, Cnt_acc}.
count_triples(A, B, C, Pow) ->
Max = trunc(math:pow(10, Pow)),
{Tot, Prim} = count_triples(A, B, C, 0, 0, Max),
{Pow, Tot, Prim}.
count_triples(Pow) ->
count_triples(3, 4, 5, Pow).
%% Display a single result.
display_result({Pow, Tot, Prim}) ->
io:format("Up to 10 ** ~w : ~w triples, ~w primitives~n", [Pow, Tot, Prim]).
main(Max) ->
L = lists:seq(1, Max),
Answer = lists:map(fun(X) -> count_triples(X) end, L),
lists:foreach(fun(Result) -> display_result(Result) end, Answer).

View file

@ -0,0 +1,21 @@
function tri(atom lim, sequence in)
sequence r
atom p
p = in[1] + in[2] + in[3]
if p > lim then
return {0, 0}
end if
r = {1, floor(lim / p)}
r += tri(lim, { in[1]-2*in[2]+2*in[3], 2*in[1]-in[2]+2*in[3], 2*in[1]-2*in[2]+3*in[3]})
r += tri(lim, { in[1]+2*in[2]+2*in[3], 2*in[1]+in[2]+2*in[3], 2*in[1]+2*in[2]+3*in[3]})
r += tri(lim, {-in[1]+2*in[2]+2*in[3], -2*in[1]+in[2]+2*in[3], -2*in[1]+2*in[2]+3*in[3]})
return r
end function
atom max_peri
max_peri = 10
while max_peri <= 100000000 do
printf(1,"%d: ", max_peri)
? tri(max_peri, {3, 4, 5})
max_peri *= 10
end while

View file

@ -0,0 +1,32 @@
let isqrt n =
let rec iter t =
let d = n - t*t
if (0 <= d) && (d < t+t+1) // t*t <= n < (t+1)*(t+1)
then t else iter ((t+(n/t))/2)
iter 1
let rec gcd a b =
let t = a % b
if t = 0 then b else gcd b t
let coprime a b = gcd a b = 1
let num_to ms =
let mutable ctr = 0
let mutable prim_ctr = 0
let max_m = isqrt (ms/2)
for m = 2 to max_m do
for j = 0 to (m/2) - 1 do
let n = m-(2*j+1)
if coprime m n then
let s = 2*m*(m+n)
if s <= ms then
ctr <- ctr + (ms/s)
prim_ctr <- prim_ctr + 1
(ctr, prim_ctr)
let show i =
let s, p = num_to i in
printfn "For perimeters up to %d there are %d total and %d primitive" i s p;;
List.iter show [ 100; 1000; 10000; 100000; 1000000; 10000000; 100000000 ]

View file

@ -0,0 +1,43 @@
USING: accessors arrays formatting kernel literals math
math.functions math.matrices math.ranges sequences ;
IN: rosettacode.pyth
CONSTANT: T1 {
{ 1 2 2 }
{ -2 -1 -2 }
{ 2 2 3 }
}
CONSTANT: T2 {
{ 1 2 2 }
{ 2 1 2 }
{ 2 2 3 }
}
CONSTANT: T3 {
{ -1 -2 -2 }
{ 2 1 2 }
{ 2 2 3 }
}
CONSTANT: base { 3 4 5 }
TUPLE: triplets-count primitives total ;
: <0-triplets-count> ( -- a ) 0 0 \ triplets-count boa ;
: next-triplet ( triplet T -- triplet' ) [ 1array ] [ m. ] bi* first ;
: candidates-triplets ( seed -- candidates )
${ T1 T2 T3 } [ next-triplet ] with map ;
: add-triplets ( current-triples limit triplet -- stop )
sum 2dup > [
/i [ + ] curry change-total
[ 1 + ] change-primitives drop t
] [ 3drop f ] if ;
: all-triplets ( current-triples limit seed -- triplets )
3dup add-triplets [
candidates-triplets [ all-triplets ] with swapd reduce
] [ 2drop ] if ;
: count-triplets ( limit -- count )
<0-triplets-count> swap base all-triplets ;
: pprint-triplet-count ( limit count -- )
[ total>> ] [ primitives>> ] bi
"Up to %d: %d triples, %d primitives.\n" printf ;
: pyth ( -- )
8 [1,b] [ 10^ dup count-triplets pprint-triplet-count ] each ;

View file

@ -0,0 +1,169 @@
\ Two methods to create Pythagorean Triples
\ this code has been tested using Win32Forth and gforth
: pythag_fibo ( f1 f0 -- )
\ Create Pythagorean Triples from 4 element Fibonacci series
\ this is called with the first two members of a 4 element Fibonacci series
\ Price and Burkhart have two good articles about this method
\ "Pythagorean Tree: A New Species" and
\ "Heron's Formula, Descartes Circles, and Pythagorean Triangles"
\ Horadam found out how to compute Pythagorean Triples from Fibonacci series
\ compute the two other members of the Fibonacci series and put them in
\ local variables. I was unable to do this with out using locals
2DUP + 2DUP + 2OVER 2DUP + 2DUP +
LOCALS| f3 f2 f1 f0 |
wk_level @ 9 .r f0 8 .r f1 8 .r f2 8 .r f3 8 .r
\ this block calculates the sides of the Pythagorean Triangle using single precision
\ f0 f3 * 14 .r \ side a (always odd)
\ 2 f1 * f2 * 10 .r \ side b (a multiple of 4)
\ f0 f2 * f1 f3 * + 10 .r \ side c, the hyponenuse, (always odd)
\ this block calculates double precision values
f0 f3 um* 15 d.r \ side a (always odd)
2 f1 * f2 um* 15 d.r \ side b (a multiple of 4)
f0 f2 um* f1 f3 um* d+ 17 d.r cr \ side c, the hypotenuse, (always odd)
MAX_LEVEL @ wk_LEVEL @ U> IF \ TRUE if MAX_LEVEL > WK_LEVEL
wk_level @ 1+ wk_level !
\ this creates a teranary tree of Pythagorean triples
\ use a two of the members of the Fibonacci series as seeds for the
\ next level
\ It's the same tree created by Barning or Hall using matrix multiplication
f3 f1 recurse
f3 f2 recurse
f0 f2 recurse
wk_level @ 1- wk_level !
else
then
drop drop drop drop ;
\ implements the Fibonacci series -- Pythagorean triple
\ the stack contents sets how many iteration levels there will be
: pf_test
\ the stack contents set up the maximum level
max_level !
0 wk_level !
cr
\ call the function with the first two elements of the base Fibonacci series
1 1 pythag_fibo ;
: gcd ( a b -- gcd )
begin ?dup while tuck mod repeat ;
\ this is the classical algorithm, known to Euclid, it is explained in many
\ books on Number Theory
\ this generates all primitive Pythagorean triples
\ i -- inner loop index or current loop index
\ j -- outer loop index
\ stack contents is the upper limit for j
\ i and j can not both be odd
\ the gcd( i, j ) must be 1
\ j is greater than i
\ the stack contains the upper limit of the j variable
: pythag_ancn ( limit -- )
cr
1 + 2 do
i 1 and if 2 else 1 then
\ this sets the start value of the inner loop so that
\ if the outer loop index is odd only even inner loop indices happen
\ if the outer loop index is even only odd inner loop indices happen
i swap do
i j gcd 1 - 0> if else \ do this if gcd( i, j ) is 1
j 5 .r i 5 .r
\ j j * i i * - 12 .r \ a side of Pythagorean triangle (always odd)
\ i j * 2 * 9 .r \ b side of Pythagorean triangle (multiple of 4)
\ i i * j j * + 9 .r \ hypotenuse of Pythagorean triangle (always odd)
\ this block calculates double precision Pythagorean triple values
j j um* i i um* d- 15 d.r \ a side of Pythagorean triangle (always odd)
i j um* d2* 15 d.r \ b side of Pythagorean triangle (multiple of 4)
i i um* j j um* d+ 17 d.r \ hypotenuse of Pythagorean triangle (always odd)
cr then 2 +loop \ keep i being all odd or all even
loop ;
Current directory: C:\Forth ok
FLOAD 'C:\Forth\ancien_fibo_pythag.F' ok
ok
ok
ok
3 pf_test
0 1 1 2 3 3 4 5
1 3 1 4 5 15 8 17
2 5 1 6 7 35 12 37
3 7 1 8 9 63 16 65
3 7 6 13 19 133 156 205
3 5 6 11 17 85 132 157
2 5 4 9 13 65 72 97
3 13 4 17 21 273 136 305
3 13 9 22 31 403 396 565
3 5 9 14 23 115 252 277
2 3 4 7 11 33 56 65
3 11 4 15 19 209 120 241
3 11 7 18 25 275 252 373
3 3 7 10 17 51 140 149
1 3 2 5 7 21 20 29
2 7 2 9 11 77 36 85
3 11 2 13 15 165 52 173
3 11 9 20 29 319 360 481
3 7 9 16 25 175 288 337
2 7 5 12 17 119 120 169
3 17 5 22 27 459 220 509
3 17 12 29 41 697 696 985
3 7 12 19 31 217 456 505
2 3 5 8 13 39 80 89
3 13 5 18 23 299 180 349
3 13 8 21 29 377 336 505
3 3 8 11 19 57 176 185
1 1 2 3 5 5 12 13
2 5 2 7 9 45 28 53
3 9 2 11 13 117 44 125
3 9 7 16 23 207 224 305
3 5 7 12 19 95 168 193
2 5 3 8 11 55 48 73
3 11 3 14 17 187 84 205
3 11 8 19 27 297 304 425
3 5 8 13 21 105 208 233
2 1 3 4 7 7 24 25
3 7 3 10 13 91 60 109
3 7 4 11 15 105 88 137
3 1 4 5 9 9 40 41
ok
ok
10 pythag_ancn
2 1 3 4 5
3 2 5 12 13
4 1 15 8 17
4 3 7 24 25
5 2 21 20 29
5 4 9 40 41
6 1 35 12 37
6 5 11 60 61
7 2 45 28 53
7 4 33 56 65
7 6 13 84 85
8 1 63 16 65
8 3 55 48 73
8 5 39 80 89
8 7 15 112 113
9 2 77 36 85
9 4 65 72 97
9 8 17 144 145
10 1 99 20 101
10 3 91 60 109
10 7 51 140 149
10 9 19 180 181
ok

View file

@ -0,0 +1,46 @@
module triples
implicit none
integer :: max_peri, prim, total
integer :: u(9,3) = reshape((/ 1, -2, 2, 2, -1, 2, 2, -2, 3, &
1, 2, 2, 2, 1, 2, 2, 2, 3, &
-1, 2, 2, -2, 1, 2, -2, 2, 3 /), &
(/ 9, 3 /))
contains
recursive subroutine new_tri(in)
integer, intent(in) :: in(:)
integer :: i
integer :: t(3), p
p = sum(in)
if (p > max_peri) return
prim = prim + 1
total = total + max_peri / p
do i = 1, 3
t(1) = sum(u(1:3, i) * in)
t(2) = sum(u(4:6, i) * in)
t(3) = sum(u(7:9, i) * in)
call new_tri(t);
end do
end subroutine new_tri
end module triples
program Pythagorean
use triples
implicit none
integer :: seed(3) = (/ 3, 4, 5 /)
max_peri = 10
do
total = 0
prim = 0
call new_tri(seed)
write(*, "(a, i10, 2(i10, a))") "Up to", max_peri, total, " triples", prim, " primitives"
if(max_peri == 100000000) exit
max_peri = max_peri * 10
end do
end program Pythagorean

View file

@ -0,0 +1,90 @@
' version 30-05-2016
' compile with: fbc -s console
' primitive pythagoras triples
' a = m^2 - n^2, b = 2mn, c = m^2 + n^2
' m, n are positive integers and m > n
' m - n = odd and GCD(m, n) = 1
' p = a + b + c
' max m for give perimeter
' p = m^2 - n^2 + 2mn + m^2 + n^2
' p = 2mn + m^2 + m^2 + n^2 - n^2 = 2mn + 2m^2
' m >> n and n = 1 ==> p = 2m + 2m^2 = 2m(1 + m)
' m >> 1 ==> p = 2m(m) = 2m^2
' max m for given perimeter = sqr(p / 2)
Function gcd(x As UInteger, y As UInteger) As UInteger
Dim As UInteger t
While y
t = y
y = x Mod y
x = t
Wend
Return x
End Function
Sub pyth_trip(limit As ULongInt, ByRef trip As ULongInt, ByRef prim As ULongInt)
Dim As ULongInt perimeter, lby2 = limit Shr 1
Dim As UInteger m, n
Dim As ULongInt a, b, c
For m = 2 To Sqr(limit / 2)
For n = 1 + (m And 1) To (m - 1) Step 2
' common divisor, try next n
If (gcd(m, n) > 1) Then Continue For
a = CULngInt(m) * m - n * n
b = CULngInt(m) * n * 2
c = CULngInt(m) * m + n * n
perimeter = a + b + c
' perimeter > limit, since n goes up try next m
If perimeter >= limit Then Continue For, For
prim += 1
If perimeter < lby2 Then
trip += limit \ perimeter
Else
trip += 1
End If
Next n
Next m
End Sub
' ------=< MAIN >=------
Dim As String str1, buffer = Space(14)
Dim As ULongInt limit, trip, prim
Dim As Double t, t1 = Timer
Print "below triples primitive time"
Print
For x As UInteger = 1 To 12
t = Timer
limit = 10 ^ x : trip = 0 : prim = 0
pyth_trip(limit, trip, prim)
LSet buffer, Str(prim) : str1 = buffer
Print Using "10^## ################ "; x; trip;
If x > 7 Then
Print str1;
Print Using " ######.## sec."; Timer - t
Else
Print str1
End If
Next x
Print : Print
Print Using "Total time needed #######.## sec."; Timer - t1
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,82 @@
' version 30-05-2016
' compile with: fbc -s console
' max m for give perimeter
' p = m^2 - n^2 + 2mn + m^2 + n^2
' p = 2mn + m^2 + m^2 + n^2 - n^2 = 2mn + 2m^2
' m >> n and n = 1 ==> p = 2m + 2m^2 = 2m(1 + m)
' m >> 1 ==> p = 2m(m) = 2m^2
' max m for given perimeter = sqr(p / 2)
Function gcd(x As UInteger, y As UInteger) As UInteger
Dim As UInteger t
While y
t = y
y = x Mod y
x = t
Wend
Return x
End Function
Sub pyth_trip_fast(limit As ULongInt, ByRef trip As ULongInt, ByRef prim As ULongInt)
Dim As ULongInt perimeter, lby2 = limit Shr 1
Dim As UInteger mx2 = 4
For m As UInteger = 2 To Sqr(limit / 2)
perimeter = (CULngInt(m) * m * 2) - IIf(m And 1, 0, m * 2)
mx2 = mx2 + 4
For n As UInteger = 1 + (m And 1) To (m - 1) Step 2
perimeter += mx2
' common divisor, try next n
If (gcd(m, n) > 1) Then Continue For
' perimeter > limit, since n goes up try next m
If perimeter >= limit Then Continue For, For
prim += 1
If perimeter < lby2 Then
trip += limit \ perimeter
Else
trip += 1
End If
Next n
Next m
End Sub
' ------=< MAIN >=------
Dim As String str1, buffer = Space(14)
Dim As ULongInt limit, trip, prim
Dim As Double t, t1 = Timer
Print "below triples primitive time"
Print
For x As UInteger = 1 To 12
t = Timer
limit = 10 ^ x : trip = 0 : prim = 0
pyth_trip_fast(limit, trip, prim)
LSet buffer, Str(prim) : str1 = buffer
Print Using "10^## ################ "; x; trip;
If x > 7 Then
Print str1;
Print Using " ######.## sec."; Timer - t
Else
Print str1
End If
Next x
Print : Print
Print Using "Total time needed #######.## sec."; Timer - t1
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,25 @@
package main
import "fmt"
var total, prim, maxPeri int64
func newTri(s0, s1, s2 int64) {
if p := s0 + s1 + s2; p <= maxPeri {
prim++
total += maxPeri / p
newTri(+1*s0-2*s1+2*s2, +2*s0-1*s1+2*s2, +2*s0-2*s1+3*s2)
newTri(+1*s0+2*s1+2*s2, +2*s0+1*s1+2*s2, +2*s0+2*s1+3*s2)
newTri(-1*s0+2*s1+2*s2, -2*s0+1*s1+2*s2, -2*s0+2*s1+3*s2)
}
}
func main() {
for maxPeri = 100; maxPeri <= 1e11; maxPeri *= 10 {
prim = 0
total = 0
newTri(3, 4, 5)
fmt.Printf("Up to %d: %d triples, %d primitives\n",
maxPeri, total, prim)
}
}

View file

@ -0,0 +1,36 @@
class Triple {
BigInteger a, b, c
def getPerimeter() { this.with { a + b + c } }
boolean isValid() { this.with { a*a + b*b == c*c } }
}
def initCounts (def n = 10) {
(n..1).collect { 10g**it }.inject ([:]) { Map map, BigInteger perimeterLimit ->
map << [(perimeterLimit): [primative: 0g, total: 0g]]
}
}
def findPythagTriples, findChildTriples
findPythagTriples = {Triple t = new Triple(a:3, b:4, c:5), Map counts = initCounts() ->
def p = t.perimeter
def currentCounts = counts.findAll { pLimit, tripleCounts -> p <= pLimit }
if (! currentCounts || ! t.valid) { return }
currentCounts.each { pLimit, tripleCounts ->
tripleCounts.with { primative ++; total += pLimit.intdiv(p) }
}
findChildTriples(t, currentCounts)
counts
}
findChildTriples = { Triple t, Map counts ->
t.with {
[
[ a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c],
[ a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c],
[-a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c]
]*.sort().each { aa, bb, cc ->
findPythagTriples(new Triple(a:aa, b:bb, c:cc), counts)
}
}
}

View file

@ -0,0 +1,5 @@
printf (' LIMIT PRIMATIVE ALL\n')
findPythagTriples().sort().each { perimeterLimit, result ->
def exponent = perimeterLimit.toString().size() - 1
printf ('a+b+c <= 10E%2d %9d %12d\n', exponent, result.primative, result.total)
}

View file

@ -0,0 +1,24 @@
pytr :: Int -> [(Bool, Int, Int, Int)]
pytr n =
filter
(\(_, a, b, c) -> a + b + c <= n)
[ (prim a b c, a, b, c)
| a <- xs,
b <- drop a xs,
c <- drop b xs,
a ^ 2 + b ^ 2 == c ^ 2
]
where
xs = [1 .. n]
prim a b _ = gcd a b == 1
main :: IO ()
main =
putStrLn $
"Up to 100 there are "
<> show (length xs)
<> " triples, of which "
<> show (length $ filter (\(x, _, _, _) -> x) xs)
<> " are primitive."
where
xs = pytr 100

View file

@ -0,0 +1,26 @@
------------------- PYTHAGOREAN TRIPLES ------------------
pythagoreanTriplesBelow :: Int -> [[Int]]
pythagoreanTriplesBelow n =
concatMap
( \x ->
concatMap
(\y -> concatMap (go x y) [y + 1 .. m])
[x + 1 .. m]
)
[1 .. m]
where
m = quot n 2
go x y z
| x + y + z <= n && x ^ 2 + y ^ 2 == z ^ 2 =
[[x, y, z]]
| otherwise = []
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_
(print . length)
( [id, filter (\[x, y, _] -> gcd x y == 1)]
<*> [pythagoreanTriplesBelow 100]
)

View file

@ -0,0 +1,24 @@
triangles :: Int -> [[Int]]
triangles max_peri
| max_peri < 12 = []
| otherwise = concat tiers
where
tiers = takeWhile (not . null) $ iterate tier [[3, 4, 5]]
tier = concatMap (filter ((<= max_peri) . sum) . tmul)
tmul t =
map
(map (sum . zipWith (*) t))
[ [[1, -2, 2], [2, -1, 2], [2, -2, 3]],
[[1, 2, 2], [2, 1, 2], [2, 2, 3]],
[[-1, 2, 2], [-2, 1, 2], [-2, 2, 3]]
]
triangleCount max_p = (length t, sum $ map ((max_p `div`) . sum) t)
where
t = triangles max_p
main :: IO ()
main =
mapM_
((putStrLn . (\n -> show n <> " " <> show (triangleCount n))) . (10 ^))
[1 .. 7]

View file

@ -0,0 +1,38 @@
link numbers
link printf
procedure main(A) # P-triples
plimit := (0 < integer(\A[1])) | 100 # get perimiter limit
nonprimitiveS := set() # record unique non-primitives triples
primitiveS := set() # record unique primitive triples
u := 0
while (g := (u +:= 1)^2) + 3 * u + 2 < plimit / 2 do {
every v := seq(1) do {
a := g + (i := 2*u*v)
b := (h := 2*v^2) + i
c := g + h + i
if (p := a + b + c) > plimit then break
insert( (gcd(u,v)=1 & u%2=1, primitiveS) | nonprimitiveS, memo(a,b,c))
every k := seq(2) do { # k is for larger non-primitives
if k*p > plimit then break
insert(nonprimitiveS,memo(a*k,b*k,c*k) )
}
}
}
printf("Under perimiter=%d: Pythagorean Triples=%d including primitives=%d\n",
plimit,*nonprimitiveS+*primitiveS,*primitiveS)
every put(gcol := [] , &collections)
printf("Time=%d, Collections: total=%d string=%d block=%d",&time,gcol[1],gcol[3],gcol[4])
end
procedure memo(x[]) #: return a csv string of arguments in sorted order
every (s := "") ||:= !sort(x) do s ||:= ","
return s[1:-1]
end

View file

@ -0,0 +1,14 @@
pytr=: 3 :0
r=. i. 0 3
for_a. 1 + i. <.(y-1)%3 do.
b=. 1 + a + i. <.(y%2)-3*a%2
c=. a +&.*: b
keep=. (c = <.c) *. y >: a+b+c
if. 1 e. keep do.
r=. r, a,.b ,.&(keep&#) c
end.
end.
(,.~ prim"1)r
)
prim=: 1 = 2 +./@{. |:

View file

@ -0,0 +1,26 @@
pytr 100
1 3 4 5
1 5 12 13
0 6 8 10
1 7 24 25
1 8 15 17
0 9 12 15
1 9 40 41
0 10 24 26
0 12 16 20
1 12 35 37
0 15 20 25
0 15 36 39
0 16 30 34
0 18 24 30
1 20 21 29
0 21 28 35
0 24 32 40
(# , [: {. +/) pytr 10
0 0
(# , [: {. +/) pytr 100
17 7
(# , [: {. +/) pytr 1000
325 70
(# , [: {. +/) pytr 10000
4858 703

View file

@ -0,0 +1,5 @@
trips=:3 :0
'm n'=. |:(#~ 1 = 2 | +/"1)(#~ >/"1) ,/ ,"0/~ }. i. <. %: y
prim=. (#~ 1 = 2 +./@{. |:) (#~ y >: +/"1)m (-&*: ,. +:@* ,. +&*:) n
/:~ ; <@(,.~ # {. 1:)@(*/~ 1 + y i.@<.@% +/)"1 prim
)

View file

@ -0,0 +1,14 @@
(# , 1 {. +/) trips 10
0 0
(# , 1 {. +/) trips 100
17 7
(# , 1 {. +/) trips 1000
325 70
(# , 1 {. +/) trips 10000
4858 703
(# , 1 {. +/) trips 100000
64741 7026
(# , 1 {. +/) trips 1000000
808950 70229
(# , 1 {. +/) trips 10000000
9706567 702309

View file

@ -0,0 +1,4 @@
trc=:3 :0
'm n'=. |:(#~ 1 = 2 | +/"1)(#~ >/"1) ,/ ,"0/~ }. i. <. %: y
<.y%+/"1 (#~ 1 = 2 +./@{. |:) (#~ y >: +/"1)m (-&*: ,. +:@* ,. +&*:) n
)

View file

@ -0,0 +1,2 @@
(#,+/)trc 1e8
7023027 113236940

View file

@ -0,0 +1,30 @@
mp =: +/ . * "2 1
T =: 3 3 3$ 1 _2 2 2 _1 2 2 _2 3 1 2 2 2 1 2 2 2 3 _1 2 2 _2 1 2 _2 2 3
branch =: dyad define NB. Go down one branch of the tree, usage: <perimeter> branch <triple>
(x >: +/"1 next) # next =. T (/:~ @ mp) y
)
pythag =: monad define NB. pythagorean triples with max perimeter
t1 =. 0 3$ 0
if. y >: 12 do.
t0 =. 1 3$ 3 4 5
while. #t0 > 0 do.
t =. {. t0
t1 =. t1, t
t0 =. (}. t0), y branch t
end.
end.
/:~ t1
)
count =: monad define "0 NB. count triples with max perimeter
y, (#t), +/ <. y % +/"1 t =. pythag y
)
(9!:11) 7 NB. change output precision
echo 'Counts of primitive and total number of Pythagorean triples with perimeter ≤ 10^n.'
echo count 10 ^ >: i.6
exit ''

View file

@ -0,0 +1,51 @@
import java.math.BigInteger;
import static java.math.BigInteger.ONE;
public class PythTrip{
public static void main(String[] args){
long tripCount = 0, primCount = 0;
//change this to whatever perimeter limit you want;the RAM's the limit
BigInteger periLimit = BigInteger.valueOf(100),
peri2 = periLimit.divide(BigInteger.valueOf(2)),
peri3 = periLimit.divide(BigInteger.valueOf(3));
for(BigInteger a = ONE; a.compareTo(peri3) < 0; a = a.add(ONE)){
BigInteger aa = a.multiply(a);
for(BigInteger b = a.add(ONE);
b.compareTo(peri2) < 0; b = b.add(ONE)){
BigInteger bb = b.multiply(b);
BigInteger ab = a.add(b);
BigInteger aabb = aa.add(bb);
for(BigInteger c = b.add(ONE);
c.compareTo(peri2) < 0; c = c.add(ONE)){
int compare = aabb.compareTo(c.multiply(c));
//if a+b+c > periLimit
if(ab.add(c).compareTo(periLimit) > 0){
break;
}
//if a^2 + b^2 != c^2
if(compare < 0){
break;
}else if (compare == 0){
tripCount++;
System.out.print(a + ", " + b + ", " + c);
//does binary GCD under the hood
if(a.gcd(b).equals(ONE)){
System.out.print(" primitive");
primCount++;
}
System.out.println();
}
}
}
}
System.out.println("Up to a perimeter of " + periLimit + ", there are "
+ tripCount + " triples, of which " + primCount + " are primitive.");
}
}

View file

@ -0,0 +1,38 @@
import java.math.BigInteger;
public class Triples{
public static BigInteger LIMIT;
public static final BigInteger TWO = BigInteger.valueOf(2);
public static final BigInteger THREE = BigInteger.valueOf(3);
public static final BigInteger FOUR = BigInteger.valueOf(4);
public static final BigInteger FIVE = BigInteger.valueOf(5);
public static long primCount = 0;
public static long tripCount = 0;
//I don't know Japanese :p
public static void parChild(BigInteger a, BigInteger b, BigInteger c){
BigInteger perim = a.add(b).add(c);
if(perim.compareTo(LIMIT) > 0) return;
primCount++; tripCount += LIMIT.divide(perim).longValue();
BigInteger a2 = TWO.multiply(a), b2 = TWO.multiply(b), c2 = TWO.multiply(c),
c3 = THREE.multiply(c);
parChild(a.subtract(b2).add(c2),
a2.subtract(b).add(c2),
a2.subtract(b2).add(c3));
parChild(a.add(b2).add(c2),
a2.add(b).add(c2),
a2.add(b2).add(c3));
parChild(a.negate().add(b2).add(c2),
a2.negate().add(b).add(c2),
a2.negate().add(b2).add(c3));
}
public static void main(String[] args){
for(long i = 100; i <= 10000000; i*=10){
LIMIT = BigInteger.valueOf(i);
primCount = tripCount = 0;
parChild(THREE, FOUR, FIVE);
System.out.println(LIMIT + ": " + tripCount + " triples, " + primCount + " primitive.");
}
}
}

View file

@ -0,0 +1,69 @@
(() => {
"use strict";
// Arguments: predicate, maximum perimeter
// pythTripleCount :: ((Int, Int, Int) -> Bool) -> Int -> Int
const pythTripleCount = p =>
maxPerim => {
const
xs = enumFromTo(1)(
Math.floor(maxPerim / 2)
);
return xs.flatMap(
x => xs.slice(x).flatMap(
y => xs.slice(y).flatMap(
z => ((x + y + z <= maxPerim) &&
((x * x) + (y * y) === z * z) &&
p(x, y, z)) ? [
[x, y, z]
] : []
)
)
).length;
};
// ---------------------- TEST -----------------------
const main = () => [10, 100, 1000]
.map(n => ({
maxPerimeter: n,
triples: pythTripleCount(() => true)(n),
primitives: pythTripleCount(
(x, y) => gcd(x)(y) === 1
)(n)
}));
// ---------------- GENERIC FUNCTIONS ----------------
// abs :: Num -> Num
const abs =
// Absolute value of a given number
// without the sign.
x => 0 > x ? (
-x
) : x;
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
// gcd :: Integral a => a -> a -> a
const gcd = x =>
y => {
const zero = x.constructor(0);
const go = (a, b) =>
zero === b ? (
a
) : go(b, a % b);
return go(abs(x), abs(y));
};
// MAIN ---
return main();
})();

View file

@ -0,0 +1,3 @@
[{"maxPerimeter":10, "triples":0, "primitives":0},
{"maxPerimeter":100, "triples":17, "primitives":7},
{"maxPerimeter":1000, "triples":325, "primitives":70}]

View file

@ -0,0 +1,37 @@
def gcd(a; b):
def _gcd:
if .[1] == 0 then .[0]
else [.[1], .[0] % .[1]] | _gcd
end;
[a,b] | _gcd ;
# Return: [total, primitives] for pythagorean triangles having
# perimeter no larger than peri.
# The following uses Euclid's formula with the convention: m > n.
def count(peri):
# The inner function can be used to count for a given value of m:
def _count:
# state [n,m,p, [total, primitives]]
.[0] as $n | .[1] as $m | .[2] as $p
| if $n < $m and $p <= peri then
if (gcd($m;$n) == 1)
then .[3] | [ (.[0] + ((peri/$p)|floor) ), (.[1] + 1)]
else .[3]
end
| [$n+2, $m, $p+4*$m, .] | _count
else .
end;
# m^2 < m*(m+1) <= m*(m+n) = perimeter/2
reduce range(2; (peri/2) | sqrt + 1) as $m
( [1, 2, 12, [0,0]];
(($m % 2) + 1) as $n
| (2 * $m * ($m + $n) ) as $p # a+b+c for this (m,n)
| [$n, $m, $p, .[3]] | _count
) | .[3] ;
# '''Example''':
def pow(i): . as $in | reduce range(0; i) as $j (1; . * $in);
range(1; 9) | . as $i | 10|pow($i) as $i | "\($i): \(count($i) )"

View file

@ -0,0 +1,9 @@
$ jq -M -c -r -n -f Pythagorean_triples.jq
10: [0,0]
100: [17,7]
1000: [325,70]
10000: [4858,703]
100000: [64741,7026]
1000000: [808950,70229]
10000000: [9706567,702309]
100000000: [113236940,7023027]

View file

@ -0,0 +1,37 @@
function primitiven{T<:Integer}(m::T)
1 < m || return T[]
m != 2 || return T[1]
!isprime(m) || return T[2:2:m-1]
rp = trues(m-1)
if isodd(m)
rp[1:2:m-1] = false
end
for p in keys(factor(m))
rp[p:p:m-1] = false
end
T[1:m-1][rp]
end
function pythagoreantripcount{T<:Integer}(plim::T)
primcnt = 0
fullcnt = 0
11 < plim || return (primcnt, fullcnt)
for m in 2:plim
p = 2m^2
p+2m <= plim || break
for n in primitiven(m)
q = p + 2m*n
q <= plim || break
primcnt += 1
fullcnt += div(plim, q)
end
end
return (primcnt, fullcnt)
end
println("Counting Pythagorian Triplets within perimeter limits:")
println(" Limit All Primitive")
for om in 1:10
(pcnt, fcnt) = pythagoreantripcount(10^om)
println(@sprintf " 10^%02d %11d %9d" om fcnt pcnt)
end

View file

@ -0,0 +1,27 @@
// version 1.1.2
var total = 0L
var prim = 0L
var maxPeri = 0L
fun newTri(s0: Long, s1: Long, s2: Long) {
val p = s0 + s1 + s2
if (p <= maxPeri) {
prim++
total += maxPeri / p
newTri( s0 - 2 * s1 + 2 * s2, 2 * s0 - s1 + 2 * s2, 2 * s0 - 2 * s1 + 3 * s2)
newTri( s0 + 2 * s1 + 2 * s2, 2 * s0 + s1 + 2 * s2, 2 * s0 + 2 * s1 + 3 * s2)
newTri(-s0 + 2 * s1 + 2 * s2, -2 * s0 + s1 + 2 * s2, -2 * s0 + 2 * s1 + 3 * s2)
}
}
fun main(args: Array<String>) {
maxPeri = 100
while (maxPeri <= 10_000_000_000L) {
prim = 0
total = 0
newTri(3, 4, 5)
println("Up to $maxPeri: $total triples, $prim primatives")
maxPeri *= 10
}
}

View file

@ -0,0 +1,18 @@
// Brute Force: Too slow for large numbers
define num_pythagorean_triples(max_perimeter::integer) => {
local(max_b) = (#max_perimeter / 3)*2
return (
with a in 1 to (#max_b - 1)
sum integer(
with b in (#a + 1) to #max_b
let c = math_sqrt(#a*#a + #b*#b)
where #c == integer(#c)
where #c > #b
where (#a+#b+#c) <= #max_perimeter
sum 1
)
)
}
stdout(`Number of Pythagorean Triples in a Perimeter of 100: `)
stdoutnl(num_pythagorean_triples(100))

View file

@ -0,0 +1,44 @@
print time$()
for power =1 to 6
perimeterLimit =10^power
upperBound =int( 1 +perimeterLimit^0.5)
primitives =0
triples =0
extras =0 ' will count the in-range multiples of any primitive
for m =2 to upperBound
for n =1 +( m mod 2 =1) to m -1 step 2
term1 =2 *m *n
term2 =m *m -n *n
term3 =m *m +n *n
perimeter =term1 +term2 +term3
if perimeter <=perimeterLimit then triples =triples +1
a =term1
b =term2
do
r = a mod b
a =b
b =r
loop until r <=0
if ( a =1) and ( perimeter <=perimeterLimit) then 'we've found a primitive triple if a =1, since hcf =1. And it is inside perimeter range. Save it in an array
primitives =primitives +1
if term1 >term2 then temp =term1: term1 =term2: term2 =temp 'swap so in increasing order of side length
nEx =int( perimeterLimit /perimeter) 'We have the primitive & removed any multiples. Now calculate ALL the multiples in range.
extras =extras +nEx
end if
scan
next n
next m
print " Number of primitives having perimeter below "; 10^power, " was "; primitives, " & "; extras, " non-primitive triples."
print time$()
next power
print "End"
end

View file

@ -0,0 +1,16 @@
N= 100;
a = 1:N;
b = a(ones(N,1),:).^2;
b = b+b';
b = sqrt(b); [y,x]=find(b==fix(b)); % test
% here some alternative tests
% b = b.^(1/k); [y,x]=find(b==fix(b)); % test 2
% [y,x]=find(b==(fix(b.^(1/k)).^k)); % test 3
% b=b.^(1/k); [y,x]=find(abs(b - round(b)) <= 4*eps*b);
z = sqrt(x.^2+y.^2);
ix = (z+x+y<100) & (x < y) & (y < z);
p = find(gcd(x(ix),y(ix))==1); % find primitive triples
printf('There are %i Pythagorean Triples and %i primitive triples with a perimeter smaller than %i.\n',...
sum(ix), length(p), N);

View file

@ -0,0 +1 @@
pythag[n_]:=Block[{soln=Solve[{a^2+b^2==c^2,a+b+c<=n,0<a<b<c},{a,b,c},Integers]},{Length[soln],Count[GCD[a,b]/.soln,1]}]

View file

@ -0,0 +1,3 @@
pTiming[n_] := With[{comp = Timing@pythag@(10^n)},
{HoldForm[10^n], comp[[2, 1]], comp[[2, 2]], Round@comp[[1]]}];
{{"n", "Triples", "Primitives", "Timing(s)"}}~Join~(pTiming /@ Range@5) // Grid

View file

@ -0,0 +1 @@
primitivePythag[p_] := Join @@ Table[If[CoprimeQ[m, n], {2 m n, m^2 - n^2, m^2 + n^2}, ## &[]],{m, 2, Floor @ Sqrt @ p},{n, 1 + m ~Mod~ 2, m, 2}] // Select[Total[#] <= p &] // Length

View file

@ -0,0 +1,2 @@
ppTiming[n_] := With[{comp = Timing@primitivePythag@(10^n)},{HoldForm[10^n], comp[[2]], Round@comp[[1]]}];
{{"n", "Primitives", "Timing(s)"}}~Join~(ppTiming /@ Range@9) // Grid

View file

@ -0,0 +1,22 @@
:- module comprehension.
:- interface.
:- import_module io.
:- import_module int.
:- type triple ---> triple(int, int, int).
:- pred pythTrip(int::in,triple::out) is nondet.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module solutions.
pythTrip(Limit,triple(X,Y,Z)) :-
nondet_int_in_range(1,Limit,X),
nondet_int_in_range(X,Limit,Y),
nondet_int_in_range(Y,Limit,Z),
pow(Z,2) = pow(X,2) + pow(Y,2).
main(!IO) :-
solutions((pred(Triple::out) is nondet :- pythTrip(20,Triple)),Result),
write(Result,!IO).

View file

@ -0,0 +1,31 @@
MODULE PyTriple64 EXPORTS Main;
IMPORT IO, Fmt;
VAR tcnt, pcnt, max, i: INTEGER;
PROCEDURE NewTriangle(a, b, c: INTEGER; VAR tcount, pcount: INTEGER) =
VAR perim := a + b + c;
BEGIN
IF perim <= max THEN
pcount := pcount + 1;
tcount := tcount + max DIV perim;
NewTriangle(a-2*b+2*c, 2*a-b+2*c, 2*a-2*b+3*c, tcount, pcount);
NewTriangle(a+2*b+2*c, 2*a+b+2*c, 2*a+2*b+3*c, tcount, pcount);
NewTriangle(2*b+2*c-a, b+2*c-2*a, 2*b+3*c-2*a, tcount, pcount);
END;
END NewTriangle;
BEGIN
i := 100;
REPEAT
max := i;
tcnt := 0;
pcnt := 0;
NewTriangle(3, 4, 5, tcnt, pcnt);
IO.Put(Fmt.Int(i) & ": " & Fmt.Int(tcnt) & " Triples, " &
Fmt.Int(pcnt) & " Primitives\n");
i := i * 10;
UNTIL i = 10000000;
END PyTriple64.

View file

@ -0,0 +1,45 @@
import math
// a function to check if three numbers are a valid triple
def is_triple(a, b, c)
if not (a < b) and (b < c)
return false
end
return (a^2 + b^2) = c^2
end
// a function to check if the numbers are coprime
def is_coprime(a, b, c)
global math
return (math.gcd(a, b)=1) && (math.gcd(a, c)=1) && (math.gcd(b, c)=1)
end
// the maximum perimeter to check
perimeter = 100
perimeter2 = int(perimeter / 2) - 1
perimeter3 = int(perimeter / 3) - 1
// loop though and look for pythagorean triples
ts = 0
ps = 0
for a in range(1, perimeter3)
for b in range(a + 1, perimeter2)
for c in range(b + 1, perimeter2)
if (a + b + c) <= perimeter
if is_triple(a,b,c)
ts += 1
print a + ", " + b + ", " + c
if is_coprime(a,b,c)
ps += 1
print " primitive"
end
println
end
end
end
end
end
print "Up to a perimeter of " + perimeter + ", there are " + ts
println " triples, of which " + ps + " are primitive."

View file

@ -0,0 +1,25 @@
const u = [[ 1, -2, 2, 2, -1, 2, 2, -2, 3],
[ 1, 2, 2, 2, 1, 2, 2, 2, 3],
[-1, 2, 2, -2, 1, 2, -2, 2, 3]]
var
total, prim = 0
maxPeri = 10
proc newTri(ins: array[0..2, int]) =
var p = ins[0] + ins[1] + ins[2]
if p > maxPeri: return
inc(prim)
total += maxPeri div p
for i in 0..2:
newTri([u[i][0] * ins[0] + u[i][1] * ins[1] + u[i][2] * ins[2],
u[i][3] * ins[0] + u[i][4] * ins[1] + u[i][5] * ins[2],
u[i][6] * ins[0] + u[i][7] * ins[1] + u[i][8] * ins[2]])
while maxPeri <= 100_000_000:
total = 0
prim = 0
newTri([3, 4, 5])
echo "Up to ", maxPeri, ": ", total, " triples, ", prim, " primitives"
maxPeri *= 10

View file

@ -0,0 +1,33 @@
let isqrt n =
let rec iter t =
let d = n - t*t in
if (0 <= d) && (d < t+t+1) (* t*t <= n < (t+1)*(t+1) *)
then t else iter ((t+(n/t))/2)
in iter 1
let rec gcd a b =
let t = a mod b in
if t = 0 then b else gcd b t
let coprime a b = gcd a b = 1
let num_to ms =
let ctr = ref 0 in
let prim_ctr = ref 0 in
let max_m = isqrt (ms/2) in
for m = 2 to max_m do
for j = 0 to (m/2) - 1 do
let n = m-(2*j+1) in
if coprime m n then
let s = 2*m*(m+n) in
if s <= ms then
(ctr := !ctr + (ms/s); incr prim_ctr)
done
done;
(!ctr, !prim_ctr)
let show i =
let s, p = num_to i in
Printf.printf "For perimeters up to %d there are %d total and %d primitive\n%!" i s p;;
List.iter show [ 100; 1000; 10000; 100000; 1000000; 10000000; 100000000 ]

View file

@ -0,0 +1,28 @@
; triples generator based on Euclid's formula, creates lazy list
(define (euclid-formula max)
(let loop ((a 3) (b 4) (c 5) (tail #null))
(if (<= (+ a b c) max)
(cons (tuple a b c) (lambda ()
(let ((d (- b)) (z (- a)))
(loop (+ a d d c c) (+ a a d c c) (+ a a d d c c c) (lambda ()
(loop (+ a b b c c) (+ a a b c c) (+ a a b b c c c) (lambda ()
(loop (+ z b b c c) (+ z z b c c) (+ z z b b c c c) tail))))))))
tail)))
; let's do calculations
(define (calculate max)
(let loop ((p 0) (t 0) (ll (euclid-formula max)))
(cond
((null? ll)
(cons p t))
((function? ll)
(loop p t (ll)))
(else
(let ((triple (car ll)))
(loop (+ p 1) (+ t (div max (apply + triple)))
(cdr ll)))))))
; print values for 10..100000
(for-each (lambda (max)
(print max ": " (calculate max)))
(map (lambda (n) (expt 10 n)) (iota 6 1)))

View file

@ -0,0 +1,15 @@
do(lim)={
my(prim,total,P);
lim\=1;
for(m=2,sqrtint(lim\2),
forstep(n=1+m%2,min(sqrtint(lim-m^2),m-1),2,
P=2*m*(m+n);
if(gcd(m,n)==1 && P<=lim,
prim++;
total+=lim\P
)
)
);
[prim,total]
};
do(100)

View file

@ -0,0 +1,37 @@
<?php
function gcd($a, $b)
{
if ($a == 0)
return $b;
if ($b == 0)
return $a;
if($a == $b)
return $a;
if($a > $b)
return gcd($a-$b, $b);
return gcd($a, $b-$a);
}
$pytha = 0;
$prim = 0;
$max_p = 100;
for ($a = 1; $a <= $max_p / 3; $a++) {
$aa = $a**2;
for ($b = $a + 1; $b < $max_p/2; $b++) {
$bb = $b**2;
for ($c = $b + 1; $c < $max_p/2; $c++) {
$cc = $c**2;
if ($aa + $bb < $cc) break;
if ($a + $b + $c > $max_p) break;
if ($aa + $bb == $cc) {
$pytha++;
if (gcd($a, $b) == 1) $prim++;
}
}
}
}
echo 'Up to ' . $max_p . ', there are ' . $pytha . ' triples, of which ' . $prim . ' are primitive.';

View file

@ -0,0 +1,90 @@
*process source attributes xref or(!);
/*********************************************************************
* REXX pgm counts number of Pythagorean triples
* that exist given a max perimeter of N,
* and also counts how many of them are primatives.
* 05.05.2013 Walter Pachl translated from REXX version 2
*********************************************************************/
pyt: Proc Options(main);
Dcl sysprint Print;
Dcl (addr,mod,right) Builtin;
Dcl memn Bin Fixed(31) Init(0);
Dcl mabca(300) Char(12);
Dcl 1 mabc,
2 ma Dec fixed(7),
2 mb Dec fixed(7),
2 mc Dec fixed(7);
Dcl mabce Char(12) Based(addr(mabc));
Dcl 1 abc,
2 a Dec fixed(7),
2 b Dec fixed(7),
2 c Dec fixed(7);
Dcl abce Char(12) Based(addr(abc));
Dcl (prims,trips,m,n,aa,aabb,cc,aeven,ab) Dec Fixed(7);
mabca='';
trips=0;
prims=0;
n=100;
la:
Do a=3 To n/3;
aa=a*a; /* limit side to 1/3 of perimeter.*/
aeven=mod(a,2)=0;
lb:Do b=a+1 By 1+aeven; /* triangle can't be isosceles. */
ab=a+b; /* compute partial perimeter. */
If ab>=n Then
Iterate la; /* a+b>perimeter? Try different A*/
aabb=aa+b*b; /* compute sum of a² + b² (cheat)*/
Do c=b+1 By 1;
cc=c*c; /* 3rd side: also compute c² */
If aeven Then
If mod(c,2)=0 Then
Iterate;
If ab+c>n Then
Iterate la; /* a+b+c > perimeter? Try diff A.*/
If cc>aabb Then
Iterate lb; /* c² > a²+b² ? Try different B.*/
If cc^=aabb Then
Iterate; /* c² ¬= a²+b² ? Try different C.*/
If mema(abce) Then
Iterate;
trips=trips+1; /* eureka. */
prims=prims+1; /* count this primitive triple. */
Put Edit(a,b,c,' ',right(a**2+b**2,5),right(c**2,5),a+b+c)
(Skip,f(4),2(f(5)),a,2(f(6)),f(9));
Do m=2 By 1;
ma=a*m;
mb=b*m;
mc=c*m; /* gen non-primitives. */
If ma+mb+mc>n Then
Leave;
/* is this multiple a triple ? */
trips=trips+1; /* yuppers, then we found another.*/
If mod(m,2)=1 Then /* store as even multiple. */
call mems(mabce);
Put Edit(ma,mb,mc,' * ',
right(ma**2+mb**2,5),right(mc**2,5),ma+mb+mc)
(Skip,f(4),2(f(5)),a,2(f(6)),f(9));
End; /* m */
End; /* c */
End; /* b */
End; /* a */
Put Edit('max perimeter = ',n, /* show a single line of output. */
'Pythagorean triples =',trips,
'primitives =',prims)
(Skip,a,f(5),2(x(9),a,f(4)));
mems: Proc(e);
Dcl e Char(12);
memn+=1;
mabca(memn)=e;
End;
mema: Proc(e) Returns(bit(1));
Dcl e Char(12);
Do memi=1 To memn;
If mabca(memi)=e Then Return('1'b);
End;
Return('0'b);
End;
End;

View file

@ -0,0 +1,32 @@
pythagorean: procedure options (main, reorder); /* 23 January 2014 */
declare (a, b, c) fixed (3);
declare (asquared, bsquared) fixed;
declare (triples, primitives) fixed binary(31) initial (0);
do a = 1 to 100;
asquared = a*a;
do b = a+1 to 100;
bsquared = b*b;
do c = b+1 to 100;
if a+b+c <= 100 then
if asquared + bsquared = c*c then
do;
triples = triples + 1;
if GCD(a,b) = 1 then primitives = primitives + 1;
end;
end;
end;
end;
put skip data (triples, primitives);
GCD: procedure (a, b) returns (fixed binary (31)) recursive;
declare (a, b) fixed binary (31);
if b = 0 then return (a);
return (GCD (b, mod(a, b)) );
end GCD;
end pythagorean;

View file

@ -0,0 +1,31 @@
Program PythagoreanTriples (output);
var
total, prim, maxPeri: int64;
procedure newTri(s0, s1, s2: int64);
var
p: int64;
begin
p := s0 + s1 + s2;
if p <= maxPeri then
begin
inc(prim);
total := total + maxPeri div p;
newTri( s0 + 2*(-s1+s2), 2*( s0+s2) - s1, 2*( s0-s1+s2) + s2);
newTri( s0 + 2*( s1+s2), 2*( s0+s2) + s1, 2*( s0+s1+s2) + s2);
newTri(-s0 + 2*( s1+s2), 2*(-s0+s2) + s1, 2*(-s0+s1+s2) + s2);
end;
end;
begin
maxPeri := 100;
while maxPeri <= 1e10 do
begin
prim := 0;
total := 0;
newTri(3, 4, 5);
writeln('Up to ', maxPeri, ': ', total, ' triples, ', prim, ' primitives.');
maxPeri := maxPeri * 10;
end;
end.

View file

@ -0,0 +1,26 @@
sub gcd {
my ($n, $m) = @_;
while($n){
my $t = $n;
$n = $m % $n;
$m = $t;
}
return $m;
}
sub tripel {
my $pmax = shift;
my $prim = 0;
my $count = 0;
my $nmax = sqrt($pmax)/2;
for( my $n=1; $n<=$nmax; $n++ ) {
for( my $m=$n+1; (my $p = 2*$m*($m+$n)) <= $pmax; $m+=2 ) {
next unless 1==gcd($m,$n);
$prim++;
$count += int $pmax/$p;
}
}
printf "Max. perimeter: %d, Total: %d, Primitive: %d\n", $pmax, $count, $prim;
}
tripel 10**$_ for 1..8;

View file

@ -0,0 +1,23 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">prim</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">maxPeri</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">tri</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s2</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s0</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">s1</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">s2</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">maxPeri</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">prim</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">total</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">maxPeri</span><span style="color: #0000FF;">/</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">tri</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*(-</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">-</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">);</span>
<span style="color: #000000;">tri</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span> <span style="color: #000000;">s1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span> <span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">);</span>
<span style="color: #000000;">tri</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span> <span style="color: #000000;">s1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*(-</span><span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*(-</span><span style="color: #000000;">s0</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">);</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">maxPeri</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">1e8</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">prim</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">;</span>
<span style="color: #000000;">total</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">;</span>
<span style="color: #000000;">tri</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">);</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Up to %d: %d triples, %d primitives.\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">maxPeri</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prim</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">maxPeri</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">;</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<!--

View file

@ -0,0 +1,36 @@
main :-
garbage_collect(300_000_000),
Data = [100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000],
member(Max, Data),
count_triples(Max, Total, Prim),
printf("upto %d, there are %d Pythagorean triples (%d primitive.)%n", Max, Total, Prim),
fail,
nl.
count_triples(Max, Total, Prims) :-
Ps = findall(S, (triple(Max, A, B, C), S is A + B + C)),
Prims = Ps.len,
Total = sum([Max div P : P in Ps]).
% - between_by/4
between_by(A, B, N, K) :-
C = (B - A) div N,
between(0, C, J),
K = N*J + A.
% - Pythagorean triple generator
triple(P, A, B, C) :-
Max = floor(sqrt(P/2)) - 1,
between(0, Max, M),
Start = (M /\ 1) + 1,
Pm = M - 1,
between_by(Start, Pm, 2, N),
gcd(M, N) == 1,
X = M*M - N*N,
Y = 2*M*N,
C = M*M + N*N,
order2(X, Y, A, B),
(A + B + C) =< P.
order2(A, B, A, B) :- A < B, !.
order2(A, B, B, A).

View file

@ -0,0 +1,20 @@
main =>
foreach(MaxPeri in [10**I : I in 2..8])
[Total, Prim] = newTri(MaxPeri,0,0,3,4,5),
printf("Up to %d: %d triples, %d primitives\n", MaxPeri, Total, Prim)
end.
newTri(MaxPeri,Prim,Total,S0, S1, S2) = [PrimRet,TotalRet] =>
P = S0 + S1 + S2,
if P <= MaxPeri then
Prim2 = Prim + 1,
Total2 = Total + MaxPeri div P,
[Prim3,Total3] = newTri(MaxPeri,Prim2,Total2, +1*S0-2*S1+2*S2, +2*S0-1*S1+2*S2, +2*S0-2*S1+3*S2),
[Prim4,Total4] = newTri(MaxPeri,Prim3,Total3, +1*S0+2*S1+2*S2, +2*S0+1*S1+2*S2, +2*S0+2*S1+3*S2),
[Prim5,Total5] = newTri(MaxPeri,Prim4,Total4, -1*S0+2*S1+2*S2, -2*S0+1*S1+2*S2, -2*S0+2*S1+3*S2),
PrimRet = Prim5,
TotalRet = Total5
else
PrimRet = Prim,
TotalRet = Total
end.

View file

@ -0,0 +1,20 @@
main =>
foreach(MaxPeri in [10**I : I in 2..8])
Map = get_global_map(),
Map.put(max_peri,MaxPeri),
Map.put(prim,0),
Map.put(total,0),
newTri3(3,4,5),
printf("Up to %d: %d triples, %d primitives\n", MaxPeri, Map.get(total), Map.get(prim))
end.
newTri2(S0, S1, S2) =>
P = S0 + S1 + S2,
Map = get_global_map(),
if P <= Map.get(max_peri) then
Map.put(prim, Map.get(prim)+1),
Map.put(total,Map.get(total) + Map.get(max_peri) div P),
newTri2(+1*S0-2*S1+2*S2, +2*S0-1*S1+2*S2, +2*S0-2*S1+3*S2),
newTri2(+1*S0+2*S1+2*S2, +2*S0+1*S1+2*S2, +2*S0+2*S1+3*S2),
newTri2(-1*S0+2*S1+2*S2, -2*S0+1*S1+2*S2, -2*S0+2*S1+3*S2)
end.

View file

@ -0,0 +1,15 @@
(for (Max 10 (>= 100000000 Max) (* Max 10))
(let (Total 0 Prim 0 In (3 4 5))
(recur (In)
(let P (apply + In)
(when (>= Max P)
(inc 'Prim)
(inc 'Total (/ Max P))
(for Row
(quote
(( 1 -2 2) ( 2 -1 2) ( 2 -2 3))
(( 1 2 2) ( 2 1 2) ( 2 2 3))
((-1 2 2) (-2 1 2) (-2 2 3)) )
(recurse
(mapcar '((U) (sum * U In)) Row) ) ) ) ) )
(prinl "Up to " Max ": " Total " triples, " Prim " primitives.") ) )

View file

@ -0,0 +1,50 @@
function triples($p) {
if($p -gt 4) {
# ai + bi + ci = pi <= p
# ai < bi < ci --> 3ai < pi <= p and ai + 2bi < pi <= p
$pa = [Math]::Floor($p/3)
1..$pa | foreach {
$ai = $_
$pb = [Math]::Floor(($p-$ai)/2)
($ai+1)..$pb | foreach {
$bi = $_
$pc = $p-$ai-$bi
($bi+1)..$pc | where {
$ci = $_
$pi = $ai + $bi + $ci
$ci*$ci -eq $ai*$ai + $bi*$bi
} |
foreach {
[pscustomobject]@{
a = "$ai"
b = "$bi"
c = "$ci"
p = "$pi"
}
}
}
}
}
else {
Write-Error "$p is not greater than 4"
}
}
function gcd ($a, $b) {
function pgcd ($n, $m) {
if($n -le $m) {
if($n -eq 0) {$m}
else{pgcd $n ($m%$n)}
}
else {pgcd $m $n}
}
$n = [Math]::Abs($a)
$m = [Math]::Abs($b)
(pgcd $n $m)
}
$triples = (triples 100)
$coprime = $triples |
where {((gcd $_.a $_.b) -eq 1) -and ((gcd $_.a $_.c) -eq 1) -and ((gcd $_.b $_.c) -eq 1)}
"There are $(($triples).Count) Pythagorean triples with perimeter no larger than 100
and $(($coprime).Count) of them are coprime."

View file

@ -0,0 +1,37 @@
show :-
Data = [100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000],
forall(
member(Max, Data),
(count_triples(Max, Total, Prim),
format("upto ~D, there are ~D Pythagorean triples (~D primitive.)~n", [Max, Total, Prim]))).
div(A, B, C) :- C is A div B.
count_triples(Max, Total, Prims) :-
findall(S, (triple(Max, A, B, C), S is A + B + C), Ps),
length(Ps, Prims),
maplist(div(Max), Ps, Counts), sumlist(Counts, Total).
% - between_by/4
between_by(A, B, N, K) :-
C is (B - A) div N,
between(0, C, J),
K is N*J + A.
% - Pythagorean triple generator
triple(P, A, B, C) :-
Max is floor(sqrt(P/2)) - 1,
between(0, Max, M),
Start is (M /\ 1) + 1, succ(Pm, M),
between_by(Start, Pm, 2, N),
gcd(M, N) =:= 1,
X is M*M - N*N,
Y is 2*M*N,
C is M*M + N*N,
order2(X, Y, A, B),
(A + B + C) =< P.
order2(A, B, A, B) :- A < B, !.
order2(A, B, B, A).

View file

@ -0,0 +1,67 @@
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")

View file

@ -0,0 +1,56 @@
from fractions import gcd
def pt1(maxperimeter=100):
'''
# Naive method
'''
trips = []
for a in range(1, maxperimeter):
aa = a*a
for b in range(a, maxperimeter-a+1):
bb = b*b
for c in range(b, maxperimeter-b-a+1):
cc = c*c
if a+b+c > maxperimeter or cc > aa + bb: break
if aa + bb == cc:
trips.append((a,b,c, gcd(a, b) == 1))
return trips
def pytrip(trip=(3,4,5),perim=100, prim=1):
a0, b0, c0 = a, b, c = sorted(trip)
t, firstprim = set(), prim>0
while a + b + c <= perim:
t.add((a, b, c, firstprim>0))
a, b, c, firstprim = a+a0, b+b0, c+c0, False
#
t2 = set()
for a, b, c, firstprim in t:
a2, a5, b2, b5, c2, c3, c7 = a*2, a*5, b*2, b*5, c*2, c*3, c*7
if a5 - b5 + c7 <= perim:
t2 |= pytrip(( a - b2 + c2, a2 - b + c2, a2 - b2 + c3), perim, firstprim)
if a5 + b5 + c7 <= perim:
t2 |= pytrip(( a + b2 + c2, a2 + b + c2, a2 + b2 + c3), perim, firstprim)
if -a5 + b5 + c7 <= perim:
t2 |= pytrip((-a + b2 + c2, -a2 + b + c2, -a2 + b2 + c3), perim, firstprim)
return t | t2
def pt2(maxperimeter=100):
'''
# Parent/child relationship method:
# http://en.wikipedia.org/wiki/Formulas_for_generating_Pythagorean_triples#XI.
'''
trips = pytrip((3,4,5), maxperimeter, 1)
return trips
def printit(maxperimeter=100, pt=pt1):
trips = pt(maxperimeter)
print(" Up to a perimeter of %i there are %i triples, of which %i are primitive"
% (maxperimeter,
len(trips),
len([prim for a,b,c,prim in trips if prim])))
for algo, mn, mx in ((pt1, 250, 2500), (pt2, 500, 20000)):
print(algo.__doc__)
for maxperimeter in range(mn, mx+1, mn):
printit(maxperimeter, algo)

View file

@ -0,0 +1,14 @@
from sys import setrecursionlimit
setrecursionlimit(2000) # 2000 ought to be big enough for everybody
def triples(lim, a = 3, b = 4, c = 5):
l = a + b + c
if l > lim: return (0, 0)
return reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), [
(1, lim / l),
triples(lim, a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c),
triples(lim, a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c),
triples(lim, -a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c) ])
for peri in [10 ** e for e in range(1, 8)]:
print peri, triples(peri)

View file

@ -0,0 +1,7 @@
10 (0, 0)
100 (7, 17)
1000 (70, 325)
10000 (703, 4858)
100000 (7026, 64741)
1000000 (70229, 808950)
10000000 (702309, 9706567)

View file

@ -0,0 +1,41 @@
[ dup 0 peek
swap 2 peek
2dup + 2dup +
join join join ] is f1 ( [ --> [ )
[ dup 3 peek
swap 1 peek
2dup + 2dup +
join join join ] is f2 ( [ --> [ )
[ dup 3 peek
swap 2 peek
2dup + 2dup +
join join join ] is f3 ( [ --> [ )
[ do over + tuck + rot * unrot * + ] is perimeter ( [ --> n )
[ stack ] is limit ( --> s )
[ stack ] is primitives ( --> s )
[ stack ] is triples ( --> s )
[ limit put
0 primitives put
0 triples put
' [ 1 1 2 3 ]
[ dup perimeter
limit share over < iff 2drop done
1 primitives tally
limit share swap / triples tally
dup f1 recurse
dup f2 recurse
f3 again ]
say "Pythagorean triples, perimeter < "
limit take echo
say ": "
triples take echo
say ", of which "
primitives take echo
say " are primitive." cr ] is task ( n --> )
7 times [ 10 i^ 2 + ** task ]

View file

@ -0,0 +1,26 @@
/*REXX program counts the number of Pythagorean triples that exist given a maximum */
/*──────────────────── perimeter of N, and also counts how many of them are primitives.*/
parse arg N . /*obtain optional argument from the CL.*/
if N=='' | N=="," then N= 100 /*Not specified? Then use the default.*/
do j=1 for N; @.j= j*j; end /*pre-compute some squares. */
N66= N * 2%3 /*calculate 2/3 of N (for a+b). */
T= 0; P= 0 /*set the number of Triples, Primitives*/
do a=3 to N%3 /*limit side to 1/3 of the perimeter.*/
do b= a+1 /*the triangle can't be isosceles. */
ab= a + b /*compute a partial perimeter (2 sides)*/
if ab>=N66 then iterate a /*is a+b≥66% perimeter? Try different A*/
aabb= @.a + @.b /*compute the sum of a²+b² (shortcut)*/
do c=b+1 /*compute the value of the third side. */
if ab+c > N then iterate a /*is a+b+c>perimeter ? Try different A.*/
if @.c >aabb then iterate b /*is c² > a²+b² ? Try " B.*/
if @.c\==aabb then iterate /*is c² ¬= a²+b² ? Try " C.*/
T= T + 1 /*eureka. We found a Pythagorean triple*/
P= P + (gcd(a, b)==1) /*is this triple a primitive triple? */
end /*c*/
end /*b*/
end /*a*/
_= left('', 7) /*for padding the output with 7 blanks.*/
say 'max perimeter =' N _ "Pythagorean triples =" T _ 'primitives =' P
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
gcd: procedure; parse arg x,y; do until y==0; parse value x//y y with y x; end; return x

View file

@ -0,0 +1,29 @@
/*REXX program counts the number of Pythagorean triples that exist given a maximum */
/*──────────────────── perimeter of N, and also counts how many of them are primitives.*/
parse arg N . /*obtain optional argument from the CL.*/
if N=='' | N=="," then N= 100 /*Not specified? Then use the default.*/
@.= 0; do j=1 for N; @.j= j*j; end /*pre-compute some squares. */
N66= N * 2%3 /*calculate 2/3 of N (for a+b). */
P= 0; T= 0; do a=3 to N%3 /*limit side to 1/3 of the perimeter.*/
aEven= a//2==0 /*set variable to 1 if A is even. */
do b=a+1 by 1+aEven; ab= a + b /*the triangle can't be isosceles. */
if ab>=N66 then iterate a /*is a+b≥66% perimeter? Try different A*/
aabb= @.a + @.b /*compute the sum of a²+b² (shortcut)*/
do c=b + 1 /*compute the value of the third side. */
if aEven then if c//2==0 then iterate /*both A&C even? Skip it*/
if ab+c>n then iterate a /*a+b+c > perimeter? Try different A. */
if @.c > aabb then iterate b /*is c² > a²+b² ? " " B. */
if @.c\==aabb then iterate /*is c² ¬= a²+b² ? " " C. */
if @.a.b.c then iterate /*Is this a duplicate? Then try again.*/
T= T + 1 /*Eureka! We found a Pythagorean triple*/
P= P + 1 /*count this also as a primitive triple*/
do m=2 while a*m+b*m+c*m<=N /*generate non-primitives Pythagoreans.*/
T= T + 1 /*Eureka! We found a Pythagorean triple*/
am= a*m; bm= b*m; cm= c*m /*create some short-cut variable names.*/
@.am.bm.cm= 1 /*mark Pythagorean triangle as a triple*/
end /*m*/
end /*c*/
end /*b*/
end /*a*/ /*stick a fork in it, we're all done. */
_= left('', 7) /*for padding the output with 7 blanks.*/
say 'max perimeter =' N _ "Pythagorean triples =" T _ 'primitives =' P

View file

@ -0,0 +1,45 @@
#lang racket
#| Euclid's enumeration formula and counting is fast enough for extra credit.
For maximum perimeter P₀, the primitive triples are enumerated by n,m with:
1 n < m
perimeter P(n, m) P₀ where P(n, m) = ( - ) + 2mn + ( + ) = 2m(m+n)
m and n of different parity and coprime.
Since n < m, a simple close non-tight bound on n is P(n, n) < P₀.
For each of these the exact set of m's can be enumerated.
Each primitive triple with perimeter p represents one triple for each kp P₀,
of which there are floor(P₀/p) k's. |#
(define (P n m) (* 2 m (+ m n)))
(define (number-of-triples P₀)
(for/fold ([primitive 0] [all 0])
([n (in-naturals 1)]
#:break (>= (P n n) P₀))
(for*/fold ([primitive primitive] [all all])
([m (in-naturals (+ n 1))]
#:break (> (P n m) P₀)
#:when (and (odd? (- m n)) (coprime? m n)))
(values (+ primitive 1)
(+ all (quotient P₀ (P n m)))))))
(define (print-results P₀)
(define-values (primitive all) (number-of-triples P₀))
(printf "~a ~a:\n ~a, ~a.\n"
"Number of Pythagorean triples and primitive triples with perimeter ≤"
P₀
all primitive))
(print-results 100)
(time (print-results (* 100 1000 1000)))
#|
Number of Pythagorean triples and primitive triples with perimeter 100:
17, 7.
Number of Pythagorean triples and primitive triples with perimeter 100000000:
113236940, 7023027.
cpu time: 11976 real time: 12215 gc time: 2381
|#

View file

@ -0,0 +1,5 @@
constant limit = 100;
for [X] [^limit] xx 3 -> (\a, \b, \c) {
say [a, b, c] if a < b < c and a + b + c <= limit and a*b + b*b == c*c
}

Some files were not shown because too many files have changed in this diff Show more