Pythagorean quadruples: Difference between revisions

Content added Content deleted
m (→‎{{header|Pascal}}: changed link to Ring version ( estimated runtime in pascal 8h10min (run outer loop 1..32 in 427783 ms ( 2 cpu-cycles per Test ) ) did it ever run?)
m (→‎{{header|Pascal}}: Give i386 a chance und improved runtime for both Cpu64/Cpu32 :-))
Line 1,123: Line 1,123:
</pre>
</pre>
=={{header|Pascal}}==
=={{header|Pascal}}==
{{works with|free pascal}} Brute froce, but not as brute as [http://rosettacode.org/mw/index.php?title=Pythagorean_quadruples#Ring Ring]. Stopping search if limit is reached<BR>
{{works with|Free Pascal}} Brute froce, but not as brute as [http://rosettacode.org/mw/index.php?title=Pythagorean_quadruples#Ring Ring].Did it ever run?<BR>
Stopping search if limit is reached<BR>
Running on Linux64 the CPU32 runs very slow.
<lang pascal>program pythQuad;
<lang pascal>program pythQuad;
//find phythagorean Quadrupel up to a,b,c,d <= 2200
//find phythagorean Quadrupel up to a,b,c,d <= 2200
Line 1,131: Line 1,131:
//brute force
//brute force
//split in two procedure to reduce register pressure for CPU32
//split in two procedure to reduce register pressure for CPU32
//23s -> 18,4 s no impact for CPU64
//{$CODEALIGN LOCALMIN=16}{$SAFEFPUEXCEPTIONS OFF/ON} no effect
//compiled with ppcx64 / ppc386 -O4 -Xs


const
const
MaxFactor = 2200;
MaxFactor =2200;
limit = MaxFactor*MaxFactor;
limit = MaxFactor*MaxFactor;
type
type
Line 1,146: Line 1,143:
checkCnt : LongWord;
checkCnt : LongWord;


procedure Find1(s:tSum;idx:tSum);
procedure Find2(s:tSum;idx:tSum);
//second sum (a*a+b*b) +c*c =?= d*d
var
var
s1 : tSum;
s1 : tSum;
posSpr : tSum;
d : tSum;
begin
begin
d := trunc(sqrt(s+idx*idx));// calculate first sqrt
For idx := idx to MaxFactor do
For idx := idx to MaxFactor do
Begin
Begin
Line 1,156: Line 1,155:
If s1 <= limit then
If s1 <= limit then
Begin
Begin
posSpr := idx; //dummy to comment out the next row
while s1 > d*d do //adjust sqrt
posSpr := round(sqrt(s1));
inc(d);
inc(checkCnt); // do something while waiting for posSqr
inc(checkCnt);
IF posSpr*posSpr=s1 then
IF s1=d*d then
check[posSpr] := true;
check[d] := true;
end
end
else
else
Line 1,167: Line 1,166:
end;
end;


procedure Find0;
procedure Find1;
//first sum a*a+b*b
var
var
i,j : tIdx;
a,b : tIdx;
s0,s1 : tSum;
s : tSum;
begin
begin
For i := 1 to MaxFactor do
For a := 1 to MaxFactor do
For b := a to MaxFactor do
Begin
s0 := i*i;
For j := i to MaxFactor do
Begin
Begin
s1 := j*j+s0;
s := a*a+b*b;
if s1 < limit then
if s < limit then
Find1(s1,j)
Find1(s,b)
else
else
break;
break;
end;
end;
end;
end;
end;


Line 1,189: Line 1,186:
i : NativeUint;
i : NativeUint;
begin
begin
find0;
Find1;

For i := 1 to MaxFactor do
For i := 1 to MaxFactor do
If Not(Check[i]) then
If Not(Check[i]) then
Line 1,199: Line 1,197:
{{out}}
{{out}}
<pre>
<pre>
CPU64:
1 2 4 5 8 10 16 20 32 40 64 80 128 160 256 320 512 640 1024 1280 2048
929605937 checks were done
real 0m2.638s -> 10,5 cpucycles per check ( Ryzen 5 1600 3,7 Ghz )

CPU32:
1 2 4 5 8 10 16 20 32 40 64 80 128 160 256 320 512 640 1024 1280 2048
1 2 4 5 8 10 16 20 32 40 64 80 128 160 256 320 512 640 1024 1280 2048
929605937 checks were done
929605937 checks were done
real 0m18.370s -> 73,5 cpucycles per check
real 0m2.323s -> 9 cpu-cycles per check on Ryzen 5 1600 3,7 Ghz ( Turbo )
lost in row: posSpr := round(sqrt(s1));
</pre>
</pre>