Pythagorean triples: Difference between revisions

m (→‎Delphi: fix edit 050404 by MaiconSoft: substitute external link to internal target by proper MediaWiki syntax)
Line 3,757:
echo 'Up to ' . $max_p . ', there are ' . $pytha . ' triples, of which ' . $prim . ' are primitive.';</lang>
{{out}}<pre>Up to 100, there are 17 triples, of which 7 are primitive.</pre>
 
=={{header|Picat}}==
===Prolog-style===
{{trans|Prolog}}
<lang Picat>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).</lang>
 
{{out}}
<pre>upto 100, there are 17 Pythagorean triples (7 primitive.)
upto 1000, there are 325 Pythagorean triples (70 primitive.)
upto 10000, there are 4857 Pythagorean triples (702 primitive.)
upto 100000, there are 64741 Pythagorean triples (7026 primitive.)
upto 1000000, there are 808950 Pythagorean triples (70229 primitive.)
upto 10000000, there are 9706567 Pythagorean triples (702309 primitive.)
upto 100000000, there are 113236940 Pythagorean triples (7023027 primitive.)
 
CPU time 4.612 seconds.</pre>
 
===Another approach===
{{trans|Go}}
Picat doesn't have global variables, so all parameters are placed in the call to <code>newTri/6</code>. This is slightly faster than the Prolog port.
 
<lang Picat>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.</lang>
 
{{out}}
<pre>Up to 100: 7 triples, 17 primitives
Up to 1000: 70 triples, 325 primitives
Up to 10000: 703 triples, 4858 primitives
Up to 100000: 7026 triples, 64741 primitives
Up to 1000000: 70229 triples, 808950 primitives
Up to 10000000: 702309 triples, 9706567 primitives
Up to 100000000: 7023027 triples, 113236940 primitives
 
CPU time 4.373 seconds.</pre>
 
===With "global variables"===
Actually, Picat has some support for global variables, using the global available map (<code>get_global_map</code>).
<lang Picat>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.</lang>
 
This version is - however - slower: 7.401s.
 
=={{header|PicoLisp}}==
495

edits