tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1,12 @@
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 coprime, 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 coprime if a and b are coprime (<math>{\rm gcd}(a, b) = 1</math>). 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. Can your program handle a max perimeter of 1,000,000? What about 10,000,000? 100,000,000?
Note: the extra credit is not for you to demonstrate how fast your language is compared to others; you need a proper algorithm to solve them in a timely manner.
;Cf:
* [[List comprehensions]]

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,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,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,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,19 @@
(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)
(let ((prim 0) (cnt 0))
(labels ((count1 (tr)
(let ((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,17 @@
import std.stdio;
ulong[2] tri(ulong lim, ulong a=3, ulong b=4, ulong c=5) {
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() {
foreach (immutable p; 1 .. 8)
writeln(10 ^^ p, " ", tri(10 ^^ p));
}

View file

@ -0,0 +1,40 @@
import std.stdio;
alias uint xuint; // ulong if going over 1 billion.
__gshared xuint nTriples, nPrimitives, limit;
void countTriples(xuint x, xuint y, xuint z) nothrow {
while (true) {
immutable xuint p = x + y + z;
if (p > limit)
return;
nPrimitives++;
nTriples += limit / p;
xuint t0 = x - 2 * y + 2 * z;
xuint t1 = 2 * x - y + 2 * z;
xuint 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 (p; 1 .. 9) {
limit = (cast(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,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,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,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,5 @@
pytr n = filter (\(_, a, b, c) -> a+b+c <= n) [(prim a b c, a, b, c) | a <- [1..n], b <- [1..n], c <- [1..n], a < b && b < c, a^2 + b^2 == c^2]
where prim a b _ = gcd a b == 1
main = putStrLn $ "Up to 100 there are " ++ (show $ length xs) ++ " triples, of which " ++ (show $ length $ filter (\(x,_,_,_) -> x == True) xs) ++ " are primitive."
where xs = pytr 100

View file

@ -0,0 +1,15 @@
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]]]
triangle_count max_p = (length t, sum $ map ((max_p `div`).sum) t)
where t = triangles max_p
main = mapM_ putStrLn $
map (\n -> show n ++ " " ++ show (triangle_count n)) $ map (10^) [1..]

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,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,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,3 @@
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] == GCD[b, c] == GCD[c, a] == 1 /. soln, True]}
]

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,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,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,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,18 @@
my %triples;
my $limit = 100;
for 3 .. $limit/2 -> $c {
for 1 .. $c -> $a {
my $b = ($c * $c - $a * $a).sqrt;
last if $c + $a + $b > $limit;
last if $a > $b;
if $b == $b.Int {
my $key = "$a $b $c";
%triples{$key} = ([gcd] $c, $a, $b.Int) > 1 ?? 0 !! 1;
say $key, %triples{$key} ?? ' - primitive' !! '';
}
}
}
say "There are {+%triples.keys} Pythagorean Triples with a perimeter <= $limit,"
~"\nof which {[+] %triples.values} are primitive.";

View file

@ -0,0 +1,20 @@
sub triples($limit) {
my $primitive = 0;
my $civilized = 0;
sub oyako($a, $b, $c) {
my $perim = $a + $b + $c;
return if $perim > $limit;
++$primitive; $civilized += $limit div $perim;
oyako( $a - 2*$b + 2*$c, 2*$a - $b + 2*$c, 2*$a - 2*$b + 3*$c);
oyako( $a + 2*$b + 2*$c, 2*$a + $b + 2*$c, 2*$a + 2*$b + 3*$c);
oyako(-$a + 2*$b + 2*$c, -2*$a + $b + 2*$c, -2*$a + 2*$b + 3*$c);
}
oyako(3,4,5);
"$limit => ($primitive $civilized)";
}
for 10,100,1000 ... * -> $limit {
say triples $limit;
}

View file

@ -0,0 +1,23 @@
constant @coeff = [[+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]];
sub triples($limit) {
sub oyako(@trippy) {
my $perim = [+] @trippy;
return if $perim > $limit;
take (1 + ($limit div $perim)i);
for @coeff -> @nine {
oyako (map -> @three { [+] @three »*« @trippy }, @nine);
}
return;
}
my $complex = 0i + [+] gather oyako([3,4,5]);
"$limit => ({$complex.re, $complex.im})";
}
for 10,100,1000 ... * -> $limit {
say triples $limit;
}

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,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,28 @@
/*REXX pgm counts number of Pythagorean triples that exist given a max */
/* perimeter of N, and also counts how many of them are primitives.*/
trips=0; prims=0
parse arg N .; if N=='' then n=100 /*get "N". If none, then assume.*/
do a=3 to N%3; aa=a*a /*limit side to 1/3 of perimeter.*/
do b=a+1 /*triangle can't be isosceles. */
ab=a+b /*compute partial perimeter. */
if ab>=n then iterate a /*a+b>perimeter? Try different A*/
aabb=aa+b*b /*compute sum of a² + b² (cheat)*/
do c=b+1; cc=c*c /*3rd side: also compute c² */
if ab+c>n then iterate a /*a+b+c > perimeter? Try diff A.*/
if cc>aabb then iterate b /*c² > a²+b² ? Try different B.*/
if cc\==aabb then iterate /*c² ¬= a²+b² ? Try different C.*/
trips=trips+1 /*eureka. */
prims=prims+(gcd(a,b)==1) /*is this triple a primative ? */
end /*a*/
end /*b*/
end /*c*/
say 'max perimeter = 'N, /*show a single line of output. */
left('',7) "Pythagorean triples =" trips, /*left('',0) ≡ 7 blanks.*/
left('',7) 'primitives =' prims
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────GCD subroutine──────────────────────*/
gcd: procedure; arg x,y; do until _==0; _=x//y; x=y; y=_; end; return x

View file

@ -0,0 +1,35 @@
/*REXX pgm counts number of Pythagorean triples that exist given a max */
/* perimeter of N, and also counts how many of them are primatives.*/
@.=0; trips=0; prims=0
parse arg N .; if N=='' then n=100 /*get "N". If none, then assume.*/
do a=3 to N%3; aa=a*a /*limit side to 1/3 of perimeter.*/
aEven=a//2==0
do b=a+1 by 1+aEven /*triangle can't be isosceles. */
ab=a+b /*compute partial perimeter. */
if ab>=n then iterate a /*a+b>perimeter? Try different A*/
aabb=aa+b*b /*compute sum of a² + b² (cheat)*/
do c=b+1; cc=c*c /*3rd side: also compute c² */
if aEven then if c//2==0 then iterate
if ab+c>n then iterate a /*a+b+c > perimeter? Try diff A.*/
if cc>aabb then iterate b /*c² > a²+b² ? Try different B.*/
if cc\==aabb then iterate /*c² ¬= a²+b² ? Try different C.*/
if @.a.b.c then iterate
trips=trips+1 /*eureka. */
prims=prims+1 /*count this primitive triple. */
do m=2; !a=a*m; !b=b*m; !c=c*m /*gen non-primitives.*/
if !a+!b+!c>N then leave /*is this multiple a triple ? */
trips=trips+1 /*yuppers, then we found another.*/
if m//2 then @.!a.!b.!c=1 /*don't mark if an even multiple.*/
end /*m*/
end /*d*/
end /*b*/
end /*a*/
say 'max perimeter = 'N, /*show a single line of output. */
left('',7) "Pythagorean triples =" trips, /*left('',0) = 7 blanks.*/
left('',7) 'primitives =' prims
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,29 @@
class PythagoranTriplesCounter
def initialize(limit)
@limit = limit
@total = 0
@primatives = 0
generate_triples(3, 4, 5)
end
attr_reader :total, :primatives
private
def generate_triples(a, b, c)
perim = a + b + c
return if perim > @limit
@primatives += 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.primatives]
perim *= 10
end

View file

@ -0,0 +1,31 @@
$ include "seed7_05.s7i";
include "bigint.s7i";
var bigInteger: total is 0_;
var bigInteger: prim is 0_;
var bigInteger: max_peri is 10_;
const proc: new_tri (in bigInteger: a, in bigInteger: b, in bigInteger: c) is func
local
var bigInteger: p is 0_;
begin
p := a + b + c;
if p <= max_peri then
incr(prim);
total +:= max_peri div p;
new_tri( a - 2_*b + 2_*c, 2_*a - b + 2_*c, 2_*a - 2_*b + 3_*c);
new_tri( a + 2_*b + 2_*c, 2_*a + b + 2_*c, 2_*a + 2_*b + 3_*c);
new_tri(-a + 2_*b + 2_*c, -2_*a + b + 2_*c, -2_*a + 2_*b + 3_*c);
end if;
end func;
const proc: main is func
begin
while max_peri <= 100000000_ do
total := 0_;
prim := 0_;
new_tri(3_, 4_, 5_);
writeln("Up to " <& max_peri <& ": " <& total <& " triples, " <& prim <& " primitives.");
max_peri *:= 10_;
end while;
end func;

View file

@ -0,0 +1,25 @@
proc countPythagoreanTriples {limit} {
lappend q 3 4 5
set idx [set count [set prim 0]]
while {$idx < [llength $q]} {
set a [lindex $q $idx]
set b [lindex $q [incr idx]]
set c [lindex $q [incr idx]]
incr idx
if {$a + $b + $c <= $limit} {
incr prim
for {set i 1} {$i*$a+$i*$b+$i*$c <= $limit} {incr i} {
incr count
}
lappend q \
[expr {$a + 2*($c-$b)}] [expr {2*($a+$c) - $b}] [expr {2*($a-$b) + 3*$c}] \
[expr {$a + 2*($b+$c)}] [expr {2*($a+$c) + $b}] [expr {2*($a+$b) + 3*$c}] \
[expr {2*($b+$c) - $a}] [expr {2*($c-$a) + $b}] [expr {2*($b-$a) + 3*$c}]
}
}
return [list $count $prim]
}
for {set i 10} {$i <= 10000000} {set i [expr {$i*10}]} {
lassign [countPythagoreanTriples $i] count primitive
puts "perimeter limit $i => $count triples, $primitive primitive"
}