Time for an 2014 update…

This commit is contained in:
Ingy döt Net 2014-01-17 05:32:22 +00:00
parent 372c577f83
commit 09687c4926
2520 changed files with 34227 additions and 7318 deletions

View file

@ -6,41 +6,41 @@ typedef unsigned long ulong;
inline ulong gcd(ulong m, ulong n)
{
ulong t;
while (n) { t = n; n = m % n; m = t; }
return m;
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;
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);
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;
/* 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++;
}
}
}
}
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);
printf("Up to %lu, there are %lu triples, of which %lu are primitive\n",
max_p, pytha, prim);
return 0;
return 0;
}

View file

@ -8,41 +8,41 @@ typedef unsigned long xint;
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}};
{ 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];
int i;
xint t[3], p = in[0] + in[1] + in[2];
if (p > max_peri) return;
if (p > max_peri) return;
prim ++;
prim ++;
/* for every primitive triangle, its multiples would be right-angled too;
* count them up to the max perimeter */
total += max_peri / p;
/* 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);
}
/* 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};
xint seed[3] = {3, 4, 5};
for (max_peri = 10; max_peri <= 100000000; max_peri *= 10) {
total = prim = 0;
new_tri(seed);
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;
printf( "Up to "FMT": "FMT" triples, "FMT" primitives.\n",
max_peri, total, prim);
}
return 0;
}

View file

@ -10,42 +10,42 @@ 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];
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;
recur: p = x + y + z;
if (p > max_peri) return;
prim ++;
total += max_peri / p;
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] = 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);
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;
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};
xint seed[3] = {3, 4, 5};
for (max_peri = 10; max_peri <= 100000000; max_peri *= 10) {
total = prim = 0;
new_tri(seed);
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;
printf( "Up to "FMT": "FMT" triples, "FMT" primitives.\n",
max_peri, total, prim);
}
return 0;
}

View file

@ -1,18 +1,18 @@
(defun mmul (a b)
(loop for x in a collect
(loop for y in x
for z in b sum (* y z))))
(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))))))
(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))))

View file

@ -4,7 +4,7 @@
-module(triples).
-export([main/1]).
%% Transformations t1, t2 and t3 to generate new triples
%% 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) ->
@ -17,10 +17,10 @@ count_triples(A, B, C, Tot_acc, Cnt_acc, Max_perimeter) when (A+B+C) =< Max_peri
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};

View file

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

View file

@ -29,10 +29,10 @@ public class Triples{
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.");
LIMIT = BigInteger.valueOf(i);
primCount = tripCount = 0;
parChild(THREE, FOUR, FIVE);
System.out.println(LIMIT + ": " + tripCount + " triples, " + primCount + " primitive.");
}
}
}

View file

@ -10,7 +10,7 @@ N= 100;
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
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

@ -5,7 +5,7 @@ sub triples($limit) {
sub oyako($a, $b, $c) {
my $perim = $a + $b + $c;
return if $perim > $limit;
++$primitive; $civilized += $limit div $perim;
++$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);

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

@ -2,13 +2,13 @@ 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) ])
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)
print peri, triples(peri)

View file

@ -1,28 +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.*/
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 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*/
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² */
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 ? */
prims=prims+(gcd(a,b)==1) /*is this triple a primitive? */
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
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

@ -1,35 +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.*/
/* perimeter of N, and also counts how many of them are primitives.*/
@.=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 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*/
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
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
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 ? */
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.*/
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. */
say 'max perimeter =' N, /*show a single line of output. */
left('',7) "Pythagorean triples =" trips, /*left('',0) = 7 blanks.*/
left('',7) 'primitives =' prims
left('',7) 'primitives =' prims
/*stick a fork in it, we're done.*/

View file

@ -2,20 +2,20 @@ 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}]
}
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]
}