Special pythagorean triplet: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(24 intermediate revisions by 16 users not shown)
Line 1:
{{Draft task}}
 
;Task:
;Task:The following problem is taken from [https://projecteuler.net/problem=9 Project Euler]
 
Find the Pythagorean triplet for which a + b + c = 1000 and print the product of a, b, and c. The problem was taken from [https://projecteuler.net/problem=9 Project Euler problem 9]
 
<br>
;Related task
* [[Pythagorean triples]]
<br><br>
=={{header|11l}}==
<syntaxhighlight lang="11l">V PERIMETER = 1000
L(a) 1 .. PERIMETER
L(b) a + 1 .. PERIMETER
V c = PERIMETER - a - b
I a * a + b * b == c * c
print((a, b, c))</syntaxhighlight>
 
{{out}}
<pre>
(200, 375, 425)
</pre>
 
=={{header|ALGOL 68}}==
Uses Euclid's formula, as in the XPL0 sample but also uses the fact that M and N must be factors of half the triangle's perimeter to reduce the number of candidate M's to check. A loop is not needed to find N once a candidate M has been found.
Using Euclid's formula, as in the XPL0 sample.
<br>Does not stop after the solution has been found, thus verifying there is only one solution.
<lang algol68>BEGIN # find the product of the of the Pythagorian triplet a, b, c where: #
<syntaxhighlight lang="algol68">BEGIN # find the product of the of the Pythagorian triplet a, b, c where: #
# a + b + c = 1000, a2 + b2 = c2, a < b < c #
INT sqrtperimeter 1000 = ENTIER sqrt( 1000 )= 1000;
INT half perimeter = perimeter OVER 2;
FOR n TO sqrt 1000 DO # m and must have different parity, i.e. one even, one odd #
INT max factor FOR m FROM n:= +half 1 BY 2 TO sqrt 1000 DOperimeter;
INT count := 0;
# a = m^2 - n^2, b = 2mn, c = m^2 + n^2 ( Euclid's formula ), so #
FOR m WHILE m < max factor DO
# a + b + c = m^2 - n^2 + 2mn + m^2 + n^2 = 2( m^2 + mn ) = 2m( m + n ) #
IF m * ( mcount + n ) := 500 THEN1;
# using Euclid's formula: INT m2 = m * m, n2 = n * n; #
# a = m^2 - n^2, b = INT2mn, ac = m2m^2 + n^2 for some integer m, n, so - n2;#
# a + b + c = m^2 INT- bn^2 =+ 2mn + m^2 *+ n^2 = 2m( m *+ n; ) #
# so m and ( m + n ) are factors of half the perimeter INT c = m2 + n2;#
IF half perimeter MOD m = 0 THEN
print( ( "a = ", whole( a, 0 ), ", b = ", whole( b, 0 ), ", c = ", whole( c, 0 ), newline ) );
# have a factor of half the perimiter print( ( "a * b * c = ", whole( a * b * c, 0 ), newline ) )#
FIINT other factor = half perimeter OVER m;
INT n = other factor - m;
OD
INT m2 = m * m, n2 = n * n;
OD
INT a := IF m > n THEN m2 - n2 ELSE n2 - m2 FI;
END</lang>
INT b := 2 * m * n;
INT c = m2 + n2;
IF ( a + b + c ) = perimeter THEN
# have found the required triple #
IF b < a THEN INT t = a; a := b; b := t FI;
print( ( "a = ", whole( a, 0 ), ", b = ", whole( b, 0 ), ", c = ", whole( c, 0 ) ) );
print( ( "; a * b * c = ", whole( a * b * c, 0 ), newline ) )
FI;
max factor := other factor
FI
OD;
print( ( whole( count, 0 ), " iterations", newline ) )
END</syntaxhighlight>
{{out}}
<pre>
a = 375200, b = 200375, c = 425; a * b * c = 31875000
24 iterations
a * b * c = 31875000
</pre>
 
Note that if we stopped after finding the solution, it would be 20 iterations.
 
=={{header|ALGOL W}}==
{{trans|Wren}}
...but doesn't stop on the first solution (thus verifying there is only one).
<langsyntaxhighlight lang="algolw">% find the Pythagorian triplet a, b, c where a + b + c = 1000 %
for a := 1 until 1000 div 3 do begin
integer a2, b;
Line 51 ⟶ 83:
end for_b ;
endB:
end for_a .</langsyntaxhighlight>
{{out}}
<pre>
Line 58 ⟶ 90:
a * b * c = 31875000
</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f SPECIAL_PYTHAGOREAN_TRIPLET.AWK
# converted from FreeBASIC
BEGIN {
main()
exit(0)
}
function main(a,b,c, limit) {
limit = 1000
for (a=1; a<=limit; a++) {
for (b=a+1; b<=limit; b++) {
for (c=b+1; c<=limit; c++) {
if (a*a + b*b == c*c) {
if (a+b+c == limit) {
printf("%d+%d+%d=%d\n",a,b,c,a+b+c)
printf("%d*%d*%d=%d\n",a,b,c,a*b*c)
return
}
}
}
}
}
}
</syntaxhighlight>
{{out}}
<pre>
200+375+425=1000
200*375*425=31875000
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <cmath>
#include <concepts>
#include <iostream>
#include <numeric>
#include <optional>
#include <tuple>
using namespace std;
 
optional<tuple<int, int ,int>> FindPerimeterTriplet(int perimeter)
{
unsigned long long perimeterULL = perimeter;
auto max_M = (unsigned long long)sqrt(perimeter/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 primitive = a + b + c;
 
// check all multiples of the primitive at once
auto factor = perimeterULL / primitive;
if(primitive * factor == perimeterULL)
{
// the triplet has been found
if(b<a) swap(a, b);
return tuple{a * factor, b * factor, c * factor};
}
}
}
 
// the triplet was not found
return nullopt;
}
int main()
{
auto t1 = FindPerimeterTriplet(1000);
if(t1)
{
auto [a, b, c] = *t1;
cout << "[" << a << ", " << b << ", " << c << "]\n";
cout << "a * b * c = " << a * b * c << "\n";
}
else
{
cout << "Perimeter not found\n";
}
}</syntaxhighlight>
{{out}}
<pre>
[200, 375, 425]
a * b * c = 31875000
</pre>
 
=={{header|Common Lisp}}==
 
A conventional solution:
 
<syntaxhighlight lang="lisp">
(defun special-triple (sum)
(loop
for a from 1
do (loop
for b from (1+ a)
for c = (- sum a b)
when (< c b) do (return)
when (= (* c c) (+ (* a a) (* b b)))
do (return-from conventional-triple-search (list a b c)))))
</syntaxhighlight>
 
This version utilizes SCREAMER which provides constraint solving:
 
<syntaxhighlight lang="lisp">
(ql:quickload "screamer")
(in-package :screamer-user)
(defun special-pythagorean-triple (sum)
(let* ((a (an-integer-between 1 (floor sum 3)))
(b (an-integer-between (1+ a) (floor (- sum a) 2)))
(c (- sum a b)))
(when (< c b) (fail))
(if (= (* c c) (+ (* a a) (* b b)))
(list a b c (* a b c))
(fail))))
 
(print (one-value (special-pythagorean-triple 1000)))
;; => (200 375 425 31875000)
</syntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
{Define structure to contain triple}
 
type TTriple = record
A, B, C: integer;
end;
 
{Make dynamic array of triples}
 
type TTripleArray = array of TTriple;
 
procedure PythagorianTriples(Limit: integer; var TA: TTripleArray);
{Find pythagorian Triple up to limit - Return result in list TA}
var Limit2: integer;
var I,J,K: integer;
begin
SetLength(TA,0);
Limit2:=Limit div 2;
for I:=1 to Limit2 do
for J:=I to Limit2 do
for K:=J to Limit do
if ((I+J+K)<Limit) and ((I*I+J*J)=(K*K)) then
begin
SetLength(TA,Length(TA)+1);
TA[High(TA)].A:=I;
TA[High(TA)].B:=J;
TA[High(TA)].C:=K;
end;
end;
 
 
procedure ShowPythagoreanTriplet(Memo: TMemo);
var TA: TTripleArray;
var I, Sum, Prod: integer;
begin
{Find triples up to 1100}
PythagorianTriples(1100,TA);
for I:=0 to High(TA) do
begin
{Look for sum of 1000}
Sum:=TA[I].A + TA[I].B + TA[I].C;
if Sum<>1000 then continue;
{Display result}
Prod:=TA[I].A * TA[I].B * TA[I].C;
Memo.Lines.Add(Format('%d + %d + %d = %10.0n',[TA[I].A, TA[I].B, TA[I].C, Sum+0.0]));
Memo.Lines.Add(Format('%d * %d * %d = %10.0n',[TA[I].A, TA[I].B, TA[I].C, Prod+0.0]));
end;
end;
 
</syntaxhighlight>
{{out}}
<pre>
200 + 375 + 425 = 1,000
200 * 375 * 425 = 31,875,000
Elapsed Time: 210.001 ms.
</pre>
 
 
=={{header|F_Sharp|F#}}==
Here I present a solution based on the ideas on the discussion page. It finds all Pythagorean triplets whose elements sum to a given value. It runs in O[n] time. Normally I would exclude triplets with a common factor but for this demonstration itI is betterprefer to leave them.
<langsyntaxhighlight lang="fsharp">
// Special pythagorean triplet. Nigel Galloway: August 31st., 2021
let fG n g=let i=(n-g)/2L in match (n+g)%2L with 0L->if (g*g)%(4L*i)=0L then Some(g,i-(g*g)/(4L*i),i+(g*g)/(4L*i)) else None
Line 67 ⟶ 294:
let E9 n=let fN=fG n in seq{1L..(n-2L)/3L}|>Seq.choose fN|>Seq.iter(fun(n,g,l)->printfn $"%d{n*n}(%d{n})+%d{g*g}(%d{g})=%d{l*l}(%d{l})")
[1L..260L]|>List.iter(fun n->printfn "Sum = %d" n; E9 n)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 434 ⟶ 661:
Real: 00:00:03.704
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' version 06-10-2021
' compile with: fbc -s console
 
' -------------------------------------------------------------
' Brute force
Dim As UInteger a, b, c
Dim As Double t1 = Timer
 
Print "Brute force" : Print
For a = 1 To 1000
For b = a+1 To 1000
For c = b+1 To 1000
If (a*a+b*b) = (c*c) Then
If a+b+c = 1000 Then
Print a,b,c
End If
End If
Next
Next
Next
 
Print
Print Using "runtime: ###.## msec.";(Timer-t1)*1000
Print String(60,"-") : Print
 
' -------------------------------------------------------------
' limit for a = 1000\3 and b = 1000\2, c = 1000 - a - c
Print "Set limits for a and b, c = 1000 - a - b" : Print
t1 = Timer
For a = 3 To 333
For b = a+1 To 500
For c= b+1 To (1000-a-b)
If a+b+c = 1000 Then
If (a*a+b*b) = (c*c) Then
Print a,b,c
Exit For,For,For
End If
End If
Next
Next
Next
 
Print
Print Using "runtime: ###.## msec.";(Timer-t1)*1000
Print String(60,"-") : Print
 
' -------------------------------------------------------------
' primative pythagoras triples
' m and n are positive integer and odd
' m > n, m start at 3
' if n > 1 then GCD(m,n) must be 1
' a = m * n
' b = (m ^ 2 - n ^ 2) \ 2
' c = (m ^ 2 + n ^ 2) \ 2
' swap a and b if a > b
 
Function gcd(x As UInteger, y As UInteger) As UInteger
 
While y
Dim As UInteger t = y
y = x Mod y
x = t
Wend
Return x
 
End Function
 
Function check(n As UInteger) As Boolean
If n And 1 = 0 Then Return FALSE
For i As UInteger = 3 To Sqr(n)
If n Mod i = 0 Then Return TRUE
Next
Return FALSE
 
End Function
 
Dim As UInteger m, n, temp
 
Print "Using primative pythagoras triples" : Print
t1 = Timer
 
For m = 3 To 201 Step 2
For n = 1 To m Step 2
If n > 1 And (gcd(m, n) <> 1) Then
Continue For
End If
a = m * n
b = (m * m - n * n) \ 2
c = b + n * n
If a > b Then Swap a, b
temp = a + b + c
If 1000 Mod temp = 0 Then
' temp must be odd and split in two number (no prime)
If check(temp) Then
temp = 1000 \ temp
a = a * temp
b = b * temp
c = c * temp
Print a,b,c
Exit For, For
End If
End If
Next
Next
 
Print
Print Using "runtime: ###.## msec.";(Timer-t1)*1000
Print String(60,"-") : Print
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>Brute force
 
200 375 425
 
runtime: 555.19 msec.
------------------------------------------------------------
 
Set limits for a and b, c = 1000 - a - b
 
200 375 425
 
runtime: 68.91 msec.
------------------------------------------------------------
 
Using primative pythagoras triples
 
200 375 425
 
runtime: 2.49 msec.
------------------------------------------------------------</pre>
 
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 461 ⟶ 826:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 475 ⟶ 840:
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<langsyntaxhighlight lang="jq">range(1;1000) as $a
| range($a+1;1000) as $b
| (1000 - $a - $b) as $c
| select($a*$a + $b*$b == $c*$c)
| {$a, $b, $c, product: ($a*$b*$c)}</langsyntaxhighlight>
{{out}}
<pre>
Line 486 ⟶ 851:
 
Or, with a tiny bit of thought:
<langsyntaxhighlight lang="jq">range(1;1000/3) as $a
| range($a+1;1000/2) as $b
| (1000 - $a - $b) as $c
| select($a*$a + $b*$b == $c*$c)
| {$a, $b, $c, product: ($a*$b*$c)}}</langsyntaxhighlight>
 
=={{header|Julia}}==
Line 507 ⟶ 872:
(a, b, c) = (200, 375, 425)
0.001073 seconds (20 allocations: 752 bytes)
</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">sol = First@
FindInstance[
a + b + c == 1000 && a > 0 && b > 0 && c > 0 &&
a^2 + b^2 == c^2, {a, b, c}, Integers];
Join[List @@@ sol, {{"Product:" , a b c /. sol}}] // TableForm</syntaxhighlight>
 
{{out}}<pre>
a 200
b 375
c 425
Product: 31875000
</pre>
 
Line 512 ⟶ 890:
My solution from Project Euler:
 
<langsyntaxhighlight Nimlang="nim">import strformat
from math import floor, sqrt
 
Line 531 ⟶ 909:
echo fmt"a: {(s - int(r)) div 2}"
echo fmt"b: {(s + int(r)) div 2}"
echo fmt"c: {c}"</langsyntaxhighlight>
 
{{out}}
Line 538 ⟶ 916:
b: 375
c: 425</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
use warnings;
 
for my $a (1 .. 998) {
my $a2 = $a**2;
for my $b ($a+1 .. 999) {
my $c = 1000 - $a - $b;
last if $c < $b;
print "$a² + $b² = $c²\n$a + $b + $c = 1000\n" and last if $a2 + $b**2 == $c**2
}
}</syntaxhighlight>
{{out}}
<pre>200² + 375² = 425²
200 + 375 + 425 = 1000</pre>
 
=={{header|Phix}}==
=== strictly adhering to the task description ===
See [[Empty_program#Phix]]
 
=== brute force (83000 iterations) ===
Not that this is in any way slow (0.1s, or 0s with the displays removed), orand not that it deliberately avoids using sensible loop limits, you understand.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1000</span>
Line 556 ⟶ 953:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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;">"%d iterations\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 564 ⟶ 961:
 
=== smarter (166 iterations) ===
It would of course be 100 iterations if we quit once found (whereas the above would be 69775).
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1000</span>
Line 580 ⟶ 977:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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;">"%d iterations\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 590 ⟶ 987:
Based on the XPL0 solution.
<br>As the original 8080 PL/M compiler only has unsigned 8 and 16 bit integer arithmetic, the PL/M [https://www.rosettacode.org/wiki/Long_multiplication long multiplication routines] and also a square root routine based that in the PL/M sample for the [https://www.rosettacode.org/wiki/Frobenius_numbers Frobenius Numbers task] are used - which makes this somewhat longer than it would otherwose be...
<langsyntaxhighlight lang="pli">100H: /* FIND THE PYTHAGOREAN TRIPLET A, B, C WHERE A + B + C = 1000 */
 
/* CP/M BDOS SYSTEM CALL */
Line 718 ⟶ 1,115:
END;
 
EOF</langsyntaxhighlight>
{{out}}
<pre>
Line 733 ⟶ 1,130:
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" perl6line>hyper for 1..998 -> $a {
my $a2 = $a²;
for $a + 1 .. 999 -> $b {
Line 741 ⟶ 1,138:
and exit if $a2 + $b² == $c²
}
}</langsyntaxhighlight>
{{out}}
<pre>200² + 375² = 425²
Line 751 ⟶ 1,148:
 
Also, there were multiple shortcuts to limit an otherwise exhaustive search; &nbsp; Once a sum or a square was too big,
<br>the next integer was used &nbsp; (for the previous DO loop).
<langsyntaxhighlight lang="rexx">/*REXX pgm computes integers A, B, C that solve: 0<A<B<C; A+B+C = 1000; A^2+B^2 = C^2 */
parse arg ssum hi n . /*obtain optional argument from the CL.*/
if ssum=='' | ssum=="," then ssum= 1000 /*Not specified? Then use the default.*/
if hi=='' | hi=="," then hi= 1000 /* " " " " " " */
if n=='' | n=="," then n= 1 /* " " " " " " */
hi2hh= hi -2 2 /*N: number of solutions to find/show.*/
do j=1 for hi; @.j= j*j /*pre─compute squares ──► HI, inclusive*/
end /*j*/
#= 0; pad= left('', 9) /*#: the number of solutions found. */
do a=2 by 2 for hi2hh%2; by 2; aa= @.a /*go huntingsearch for solutions to the equations*/
do b=a+1; for hi2-a; ab= a + b /*calculatecompute the sum of two2 numbers (A,B) & squaresB).*/
if ab>hi hh then iterate a /*Sum of A+B>HI? Then stop with B's */
aabb= aa + @.b /*compute the sum of: A^2 + B^2 */
do c=b+1 for hi2-b while @.c <= aabb /*test integers that satisfy equations.*/
if @.c\==aabb then iterate > aabb then iterate b /*Square> " \=A^2+B^2? Then stopkeep with C's.searching*/
abc= ab if+ @.c \== aabb then iterate /*compute the sum of: " \=A^2 + B^2? Then+ C keep searching*/
if abc= ab + c > sum then iterate b /*compute the sum ofIs A + B+C > +SUM? C Then stop with C's.*/
if abc == ssum then call show then call show /*Does A+B+C " = SSUM? Then solution found*/
end /*c*/
if abc > s then iterate b /*Is " > S? Then stop with C's.*/
end end /*cb*/
end end /*ba*/
done: if #==0 then #= 'no'; say pad pad pad # ' solution's(#) "found."
end /*a*/
done: say pad pad pad # ' solutions found.'
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*simple pluralizer*/
show: #= #+1; say pad 'a=' a pad "b=" b pad 'c=' c; if #>=n then signal done; return</lang>
show: #= #+1; say pad 'a=' a pad "b=" b pad 'c=' c; if #>=n then signal done; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
a= 200 b= 375 c= 425
1 solutionssolution found.
</pre>
 
=={{header|Ring}}==
Various algorithms presented, some are quite fast. Timings are from Tio.run. On the desktop of a core i7-7700 @ 3.60Ghz, it goes about 6.5 times faster.
<lang ring>
<syntaxhighlight lang="ring">tf = 1000 # time factor adjustment for different Ring versions
load "stdlib.ring"
see "working..." + nl
 
? "working..."
time1 = clock()
 
for a = 1 to 1000
? "turtle method:" # 3 nested loops is not a good approach,
for b = a+1 to 1000
# even when cheating by cherry-picking the loop start/end points...
for c = b+1 to 1000
st = clock()
if (pow(a,2)+pow(b,2)=pow(c,2))
 
if a+b+c = 1000
for a = 100 to 400
see "a = " + a + " b = " + b + " c = " + c + nl
for b = 200 to exit 3800
for c = b to 1000 - a - b
if a + b + c = 1000
if a * a + b * b = c * c exit 3 ok
ok
oknext
next
next
next
et = clock() - st
? "a = " + a + " b = " + b + " c = " + c
? "Elapsed time = " + et / (tf * 1000) + " s" + nl
 
? "brutally forced method:" # eliminating the "c" loop speeds it up a bit
time2 = clock()
st = clock()
time3 = time2/1000 - time1/1000
 
see "Elapsed time = " + time3 + " s" + nl
for a = 1 to 1000
see "done..." + nl
for b = a to 1000
</lang>
c = 1000 - a - b
if a * a + b * b = c * c exit 2 ok
next
next
et = clock() - st
? "a = " + a + " b = " + b + " c = " + c
? "Elapsed time = " + et / tf + " ms" + nl
# some basic info about this task:
p = 1000 pp = p * p >> 1 # perimeter, half of perimeter^2
maxc = ceil(sqrt(pp) * 2) - p # minimum c = 415 ceiling of ‭414.2135623730950488016887242097‬
maxa = (p - maxc) >> 1 # maximum a = 292, shorter leg will shrink
minb = p - maxc - maxa # minimum b = 293, longer leg will lengthen
 
? "polished brute force method:" # calculated realistic limits for the loops,
# cached some vars that didn't need recalcs over and over
st = clock()
minb = maxa + 1 maxb = p - maxc pma = p - 1
for a = 1 to maxa
aa = a * a
c = pma - minb
for b = minb to maxb
if aa + b * b = c * c exit 2 ok
c--
next
pma--
next
et = clock() - st
? "a = " + a + " b = " + b + " c = " + c
? "Elapsed time = " + et / tf + " ms" + nl
? "quick method:" # down to one loop, using some math insight
st = clock()
n2 = p >> 1
for a = 1 to n2
b = p * (n2 - a)
if b % (p - a) = 0 exit ok
next
b /= (p - a)
? "a = " + a + " b = " + b + " c = " + (p - a - b)
et = clock() - st
? "Elapsed time = " + et / tf + " ms" + nl
 
? "even quicker method:" # generate primitive Pythagorean triples,
# then scale to fit the actual perimeter
st = clock()
md = 1 ms = 1
for m = 1 to 4
nd = md + 2 ns = ms + nd
for n = m + 1 to 5
if p % (((n * m) + ns) << 1) = 0 exit 2 ok
nd += 2 ns += nd
next
md += 2 ms += md
next
et = clock() - st
a = n * m << 1 b = ns - ms c = ns + ms d = p / (((n * m) + ns) << 1)
? "a = " + a * d + " b = " + b * d + " c = " + c * d
? "Elapsed time = " + et / tf + " ms" + nl
 
? "alternate method:" # only uses addition / subtraction inside the loop.
# makes a guess, then tweaks the guess until correct
st = clock()
a = maxa b = minb
g = p * (a + b) - a * b # guess
while g != pp
if pp > g
b++ g += p - a # step "b" only when the "a" step went too far
ok
a-- g -= p - b # step "a" on every iteration
end
et = clock() - st
? "a = " + a + " b = " + b + " c = " + (p - a - b)
? "Elapsed time = " + et / tf + " ms" + nl
 
see "done..."</syntaxhighlight>
{{out}}
<pre>working...
turtle method:
working...
a = 200 b = 375 c = 425
Elapsed time = 49713.6136 s
 
done...
brutally forced method:
a = 200 b = 375 c = 425
Elapsed time = 983.94 ms
 
polished brute force method:
a = 200 b = 375 c = 425
Elapsed time = 216.66 ms
 
quick method:
a = 200 b = 375 c = 425
Elapsed time = 0.97 ms
 
even quicker method:
a = 200 b = 375 c = 425
Elapsed time = 0.18 ms
 
alternate method:
a = 200 b = 375 c = 425
Elapsed time = 0.44 ms
 
done...</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use std::collections::HashSet ;
 
fn main() {
let mut numbers : HashSet<u32> = HashSet::new( ) ;
for a in 1u32..=1000u32 {
for b in 1u32..=1000u32 {
for c in 1u32..=1000u32 {
if a + b + c == 1000 && a * a + b * b == c * c {
numbers.insert( a ) ;
numbers.insert( b ) ;
numbers.insert( c ) ;
}
}
}
}
let mut product : u32 = 1 ;
for k in &numbers {
product *= *k ;
}
println!("{:?}" , numbers ) ;
println!("The product of {:?} is {}" , numbers , product) ;
}
</syntaxhighlight>
{{out}}
<pre>
{375, 425, 200}
The product of {375, 425, 200} is 31875000
</pre>
 
=={{header|Wren}}==
Very simple approach, only takes 0.013 seconds even in Wren.
<langsyntaxhighlight ecmascriptlang="wren">var a = 3
while (true) {
var b = a + 1
Line 833 ⟶ 1,363:
}
a = a + 1
}</langsyntaxhighlight>
 
{{out}}
Line 843 ⟶ 1,373:
<br>
Incidentally, even though we are '''told''' there is only one solution, it is almost as quick to verify this by observing that, since a < b < c, the maximum value of a must be such that 3a + 2 = 1000 or max(a) = 332. The following version ran in 0.015 seconds and, of course, produced the same output:
<langsyntaxhighlight ecmascriptlang="wren">for (a in 3..332) {
var b = a + 1
while (true) {
Line 855 ⟶ 1,385:
b = b + 1
}
}</langsyntaxhighlight>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">int N, M, A, B, C;
for N:= 1 to sqrt(1000) do
for M:= N+1 to sqrt(1000) do
Line 866 ⟶ 1,396:
if A+B+C = 1000 then
IntOut(0, A*B*C);
]</langsyntaxhighlight>
 
{{out}}
9,476

edits