Special pythagorean triplet

From Rosetta Code
Special pythagorean triplet is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Find the Pythagorean triplet for which a + b + c = 1000 and print the product of a, b, and c. The problem was taken from Project Euler problem 9


Related task



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))
Output:
(200, 375, 425)

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.
Does not stop after the solution has been found, thus verifying there is only one solution.

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  perimeter      = 1000;
    INT  half perimeter = perimeter OVER 2;
    INT  max factor    := half perimeter;
    INT  count         := 0;
    FOR m WHILE m < max factor DO
        count +:= 1;
        # using Euclid's formula:                                            #
        # a = m^2 - n^2, b = 2mn, c = m^2 + n^2 for some integer m, n, so    #
        # a + b + c = m^2 - n^2 + 2mn + m^2 + n^2 = 2m( m + n )              #
        # so m and ( m + n ) are factors of half the perimeter               #
        IF half perimeter MOD m = 0 THEN
            # have a factor of half the perimiter                            #
            INT other factor = half perimeter OVER m;
            INT n            = other factor - m;
            INT m2 = m * m, n2 = n * n;
            INT a := IF m > n THEN m2 - n2 ELSE n2 - m2 FI;
            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
Output:
a = 200, b = 375, c = 425; a * b * c = 31875000
24 iterations

Note that if we stopped after finding the solution, it would be 20 iterations.

ALGOL W

Translation of: Wren

...but doesn't stop on the first solution (thus verifying there is only one).

% find the Pythagorian triplet a, b, c where a + b + c = 1000 %
for a := 1 until 1000 div 3 do begin
    integer a2, b;
    a2 := a * a;
    for b := a + 1 until 1000 do begin
        integer c;
        c := 1000 - ( a + b );
        if c <= b then goto endB;
        if a2 + b*b = c*c then begin
            write( i_w := 1, s_w := 0, "a = ", a, ", b = ", b, ", c = ", c );
            write( i_w := 1, s_w := 0, "a + b + c = ", a + b + c );
            write( i_w := 1, s_w := 0, "a * b * c = ", a * b * c )
        end if_a2_plus_b2_e_c2 ;
        b := b + 1
    end for_b ;
endB:
end for_a .
Output:
a = 200, b = 375, c = 425
a + b + c = 1000
a * b * c = 31875000

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
            }
          }
        }
      }
    }
}
Output:
200+375+425=1000
200*375*425=31875000

C++

#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";
  }
}
Output:
[200, 375, 425]
a * b * c = 31875000

Common Lisp

A conventional solution:

(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)))))

This version utilizes SCREAMER which provides constraint solving:

(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)

Delphi

Works with: Delphi version 6.0


{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;
Output:
200 + 375 + 425 =      1,000
200 * 375 * 425 = 31,875,000
Elapsed Time: 210.001 ms.


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 I prefer to leave them.

// 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
                                                |_->if (g*g-2L*i-1L)%(4L*i+2L)=0L then Some(g,i-(g*g)/(4L*i+2L),i+1L+(g*g)/(4L*i+2L)) else None
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)
Output:
Sum = 1
Sum = 2
Sum = 3
Sum = 4
Sum = 5
Sum = 6
Sum = 7
Sum = 8
Sum = 9
Sum = 10
Sum = 11
Sum = 12
9(3)+16(4)=25(5)
Sum = 13
Sum = 14
Sum = 15
Sum = 16
Sum = 17
Sum = 18
Sum = 19
Sum = 20
Sum = 21
Sum = 22
Sum = 23
Sum = 24
36(6)+64(8)=100(10)
Sum = 25
Sum = 26
Sum = 27
Sum = 28
Sum = 29
Sum = 30
25(5)+144(12)=169(13)
Sum = 31
Sum = 32
Sum = 33
Sum = 34
Sum = 35
Sum = 36
81(9)+144(12)=225(15)
Sum = 37
Sum = 38
Sum = 39
Sum = 40
64(8)+225(15)=289(17)
Sum = 41
Sum = 42
Sum = 43
Sum = 44
Sum = 45
Sum = 46
Sum = 47
Sum = 48
144(12)+256(16)=400(20)
Sum = 49
Sum = 50
Sum = 51
Sum = 52
Sum = 53
Sum = 54
Sum = 55
Sum = 56
49(7)+576(24)=625(25)
Sum = 57
Sum = 58
Sum = 59
Sum = 60
100(10)+576(24)=676(26)
225(15)+400(20)=625(25)
Sum = 61
Sum = 62
Sum = 63
Sum = 64
Sum = 65
Sum = 66
Sum = 67
Sum = 68
Sum = 69
Sum = 70
400(20)+441(21)=841(29)
441(21)+400(20)=841(29)
Sum = 71
Sum = 72
324(18)+576(24)=900(30)
Sum = 73
Sum = 74
Sum = 75
Sum = 76
Sum = 77
Sum = 78
Sum = 79
Sum = 80
256(16)+900(30)=1156(34)
Sum = 81
Sum = 82
Sum = 83
Sum = 84
144(12)+1225(35)=1369(37)
441(21)+784(28)=1225(35)
Sum = 85
Sum = 86
Sum = 87
Sum = 88
Sum = 89
Sum = 90
81(9)+1600(40)=1681(41)
225(15)+1296(36)=1521(39)
Sum = 91
Sum = 92
Sum = 93
Sum = 94
Sum = 95
Sum = 96
576(24)+1024(32)=1600(40)
Sum = 97
Sum = 98
Sum = 99
Sum = 100
Sum = 101
Sum = 102
Sum = 103
Sum = 104
Sum = 105
Sum = 106
Sum = 107
Sum = 108
729(27)+1296(36)=2025(45)
Sum = 109
Sum = 110
Sum = 111
Sum = 112
196(14)+2304(48)=2500(50)
Sum = 113
Sum = 114
Sum = 115
Sum = 116
Sum = 117
Sum = 118
Sum = 119
Sum = 120
400(20)+2304(48)=2704(52)
576(24)+2025(45)=2601(51)
900(30)+1600(40)=2500(50)
Sum = 121
Sum = 122
Sum = 123
Sum = 124
Sum = 125
Sum = 126
784(28)+2025(45)=2809(53)
Sum = 127
Sum = 128
Sum = 129
Sum = 130
Sum = 131
Sum = 132
121(11)+3600(60)=3721(61)
1089(33)+1936(44)=3025(55)
Sum = 133
Sum = 134
Sum = 135
Sum = 136
Sum = 137
Sum = 138
Sum = 139
Sum = 140
1600(40)+1764(42)=3364(58)
1764(42)+1600(40)=3364(58)
Sum = 141
Sum = 142
Sum = 143
Sum = 144
256(16)+3969(63)=4225(65)
1296(36)+2304(48)=3600(60)
Sum = 145
Sum = 146
Sum = 147
Sum = 148
Sum = 149
Sum = 150
625(25)+3600(60)=4225(65)
Sum = 151
Sum = 152
Sum = 153
Sum = 154
1089(33)+3136(56)=4225(65)
Sum = 155
Sum = 156
1521(39)+2704(52)=4225(65)
Sum = 157
Sum = 158
Sum = 159
Sum = 160
1024(32)+3600(60)=4624(68)
Sum = 161
Sum = 162
Sum = 163
Sum = 164
Sum = 165
Sum = 166
Sum = 167
Sum = 168
441(21)+5184(72)=5625(75)
576(24)+4900(70)=5476(74)
1764(42)+3136(56)=4900(70)
Sum = 169
Sum = 170
Sum = 171
Sum = 172
Sum = 173
Sum = 174
Sum = 175
Sum = 176
2304(48)+3025(55)=5329(73)
3025(55)+2304(48)=5329(73)
Sum = 177
Sum = 178
Sum = 179
Sum = 180
324(18)+6400(80)=6724(82)
900(30)+5184(72)=6084(78)
2025(45)+3600(60)=5625(75)
Sum = 181
Sum = 182
169(13)+7056(84)=7225(85)
Sum = 183
Sum = 184
Sum = 185
Sum = 186
Sum = 187
Sum = 188
Sum = 189
Sum = 190
Sum = 191
Sum = 192
2304(48)+4096(64)=6400(80)
Sum = 193
Sum = 194
Sum = 195
Sum = 196
Sum = 197
Sum = 198
1296(36)+5929(77)=7225(85)
Sum = 199
Sum = 200
1600(40)+5625(75)=7225(85)
Sum = 201
Sum = 202
Sum = 203
Sum = 204
2601(51)+4624(68)=7225(85)
Sum = 205
Sum = 206
Sum = 207
Sum = 208
1521(39)+6400(80)=7921(89)
Sum = 209
Sum = 210
1225(35)+7056(84)=8281(91)
3600(60)+3969(63)=7569(87)
3969(63)+3600(60)=7569(87)
Sum = 211
Sum = 212
Sum = 213
Sum = 214
Sum = 215
Sum = 216
2916(54)+5184(72)=8100(90)
Sum = 217
Sum = 218
Sum = 219
Sum = 220
400(20)+9801(99)=10201(101)
Sum = 221
Sum = 222
Sum = 223
Sum = 224
784(28)+9216(96)=10000(100)
Sum = 225
Sum = 226
Sum = 227
Sum = 228
3249(57)+5776(76)=9025(95)
Sum = 229
Sum = 230
Sum = 231
Sum = 232
Sum = 233
Sum = 234
4225(65)+5184(72)=9409(97)
5184(72)+4225(65)=9409(97)
Sum = 235
Sum = 236
Sum = 237
Sum = 238
Sum = 239
Sum = 240
225(15)+12544(112)=12769(113)
1600(40)+9216(96)=10816(104)
2304(48)+8100(90)=10404(102)
3600(60)+6400(80)=10000(100)
Sum = 241
Sum = 242
Sum = 243
Sum = 244
Sum = 245
Sum = 246
Sum = 247
Sum = 248
Sum = 249
Sum = 250
Sum = 251
Sum = 252
1296(36)+11025(105)=12321(111)
3136(56)+8100(90)=11236(106)
3969(63)+7056(84)=11025(105)
Sum = 253
Sum = 254
Sum = 255
Sum = 256
Sum = 257
Sum = 258
Sum = 259
Sum = 260
3600(60)+8281(91)=11881(109)

I present results with timing for increasing powers of 10 to demonstrate its O[n] running.

E9 1000L
40000(200)+140625(375)=180625(425)
Real: 00:00:00.001

E9 10000L
4000000(2000)+14062500(3750)=18062500(4250)
Real: 00:00:00.000

E9 100000L
400000000(20000)+1406250000(37500)=1806250000(42500)
478515625(21875)+1296000000(36000)=1774515625(42125)
Real: 00:00:00.001

E9 1000000L
40000000000(200000)+140625000000(375000)=180625000000(425000)
47851562500(218750)+129600000000(360000)=177451562500(421250)
Real: 00:00:00.005

E9 10000000L
54931640625(234375)+23814400000000(4880000)=23869331640625(4885625)
4000000000000(2000000)+14062500000000(3750000)=18062500000000(4250000)
4785156250000(2187500)+12960000000000(3600000)=17745156250000(4212500)
Real: 00:00:00.040

E9 100000000L
5493164062500(2343750)+2381440000000000(48800000)=2386933164062500(48856250)
400000000000000(20000000)+1406250000000000(37500000)=1806250000000000(42500000)
478515625000000(21875000)+1296000000000000(36000000)=1774515625000000(42125000)
Real: 00:00:00.382

E9 1000000000L
549316406250000(23437500)+238144000000000000(488000000)=238693316406250000(488562500)
40000000000000000(200000000)+140625000000000000(375000000)=180625000000000000(425000000)
47851562500000000(218750000)+129600000000000000(360000000)=177451562500000000(421250000)
Real: 00:00:03.704

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
Output:
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.
------------------------------------------------------------

Go

Translation of: Wren
package main

import (
    "fmt"
    "time"
)

func main() {
    start := time.Now()
    for a := 3; ; a++ {
        for b := a + 1; ; b++ {
            c := 1000 - a - b
            if c <= b {
                break
            }
            if a*a+b*b == c*c {
                fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
                fmt.Println("a + b + c =", a+b+c)
                fmt.Println("a * b * c =", a*b*c)
                fmt.Println("\nTook", time.Since(start))
                return
            }
        }
    }
}
Output:
a = 200, b = 375, c = 425
a + b + c = 1000
a * b * c = 31875000

Took 77.664µs

jq

Works with: jq

Works with gojq, the Go implementation of 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)}
Output:
{"a":200,"b":375,"c":425,"product":31875000}

Or, with a tiny bit of thought:

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)}}

Julia

julia> [(a, b, c) for a in 1:1000, b in 1:1000, c in 1:1000 if a < b < c && a + b + c == 1000 && a^2 + b^2 == c^2]
1-element Vector{Tuple{Int64, Int64, Int64}}:
 (200, 375, 425)

or, with attention to timing:

julia> @time for a in 1:1000
           for b in a+1:1000
               c = 1000 - a - b; a^2 + b^2 == c^2 && @show a, b, c
           end
       end
(a, b, c) = (200, 375, 425)
  0.001073 seconds (20 allocations: 752 bytes)

Mathematica / Wolfram Language

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
Output:

a 200 b 375 c 425 Product: 31875000

Nim

My solution from Project Euler:

import strformat
from math import floor, sqrt

var
  p, s, c : int
  r: float

for i in countdown(499, 1):
  s = 1000 - i
  p = 1000 * (500 - i)
  let delta = float(s * s - 4 * p)
  r = sqrt(delta)
  if floor(r) == r:
    c = i
    break

echo fmt"Product: {p * c}"
echo fmt"a: {(s - int(r)) div 2}"
echo fmt"b: {(s + int(r)) div 2}"
echo fmt"c: {c}"
Output:
Product: 31875000
a: 200
b: 375
c: 425

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
    }
}
Output:
200² + 375² = 425²
200  + 375  + 425 = 1000

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), and not that it deliberately avoids using sensible loop limits, you understand.

with javascript_semantics
constant n = 1000
integer count = 0
for a=1 to floor(n/3) do
    for b=a+1 to floor((n-a)/2) do
        count += 1
        integer c = n-(a+b)
        if a*a+b*b=c*c then
            printf(1,"a=%d, b=%d, c=%d, a*b*c=%d\n",{a,b,c,a*b*c})
        end if
    end for
end for
printf(1,"%d iterations\n",count)
Output:
a=200, b=375, c=425, a*b*c=31875000
83000 iterations

smarter (166 iterations)

It would of course be 100 iterations if we quit once found (whereas the above would be 69775).

with javascript_semantics
constant n = 1000
integer count = 0
for a=2 to floor(n/3) by 2 do
    count += 1
    integer nn2a = n*(n/2-a),
            na = n-a
    if remainder(nn2a,na)=0 then
        integer b = nn2a/na,
                c = n-(a+b)
        printf(1,"a=%d, b=%d, c=%d, a*b*c=%d\n",{a,b,c,a*b*c})
    end if
end for
printf(1,"%d iterations\n",count)
Output:
a=200, b=375, c=425, a*b*c=31875000
166 iterations

PL/M

Based on the XPL0 solution.
As the original 8080 PL/M compiler only has unsigned 8 and 16 bit integer arithmetic, the PL/M long multiplication routines and also a square root routine based that in the PL/M sample for the Frobenius Numbers task are used - which makes this somewhat longer than it would otherwose be...

100H: /* FIND THE PYTHAGOREAN TRIPLET A, B, C WHERE A + B + C = 1000        */

   /* CP/M BDOS SYSTEM CALL                                                 */
   BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
   /* I/O ROUTINES                                                          */
   PRINT$CHAR:   PROCEDURE( C ); DECLARE C BYTE;    CALL BDOS( 2, C ); END;
   PRINT$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
   PRINT$NL:     PROCEDURE;   CALL PRINT$STRING( .( 0DH, 0AH, '$' ) ); END;

   /* LONG MULTIPLICATION                                                   */
   /* LARGE INTEGERS ARE REPRESENTED BY ARRAYS OF BYTES WHOSE VALUES ARE    */
   /* A SINGLE DECIMAL DIGIT OF THE NUMBER                                  */
   /* THE LEAST SIGNIFICANT DIGIT OF THE LARGE INTEGER IS IN ELEMENT 1      */
   /* ELEMENT 0 CONTAINS THE NUMBER OF DIGITS THE NUMBER HAS                */
   DECLARE LONG$INTEGER  LITERALLY '(21)BYTE';
   DECLARE DIGIT$BASE    LITERALLY '10';
   /* PRINTS A LONG INTEGER                                                 */
   PRINT$LONG$INTEGER: PROCEDURE( N$PTR );
      DECLARE N$PTR ADDRESS;
      DECLARE N BASED N$PTR LONG$INTEGER;
      DECLARE ( D, F ) BYTE;
      F = N( 0 );
      DO D = 1 TO N( 0 );
         CALL PRINT$CHAR( N( F ) + '0' );
         F = F - 1;
      END;
   END PRINT$LONG$INTEGER;
   /* SETS A LONG$INTEGER TO A 16-BIT VALUE                                 */
   SET$LONG$INTEGER: PROCEDURE( LN, N );
      DECLARE ( LN, N ) ADDRESS;
      DECLARE V ADDRESS;
      DECLARE LN$PTR ADDRESS, LN$BYTE  BASED LN$PTR BYTE;
      DECLARE LN$0   ADDRESS, LN$0BYTE BASED LN$0   BYTE;
      LN$0, LN$PTR = LN;
      LN$0BYTE     = 1;
      LN$PTR       = LN$PTR + 1;
      LN$BYTE      = ( V := N ) MOD DIGIT$BASE;
      DO WHILE( ( V := V / DIGIT$BASE ) > 0 );
         LN$PTR   = LN$PTR   + 1;
         LN$BYTE  = V MOD DIGIT$BASE;
         LN$0BYTE = LN$0BYTE + 1;
      END;
   END SET$LONG$INTEGER;
   /* IMPLEMENTS LONG MULTIPLICATION, C IS SET TO A * B                     */
   /*     C CAN BE THE SAME LONG$INTEGER AS A OR B                          */
   LONG$MULTIPLY: PROCEDURE( A$PTR, B$PTR, C$PTR );
      DECLARE ( A$PTR, B$PTR, C$PTR ) ADDRESS;
      DECLARE ( A BASED A$PTR, B BASED B$PTR, C BASED C$PTR ) LONG$INTEGER;
      DECLARE MRESULT LONG$INTEGER;
      DECLARE RPOS    BYTE;

      /* MULTIPLIES THE LONG INTEGER IN B BY THE INTEGER A, THE RESULT      */
      /*     IS ADDED TO C, STARTING FROM DIGIT START                       */
      /*     OVERFLOW IS IGNORED                                            */
      MULTIPLY$ELEMENT: PROCEDURE( A, B$PTR, C$PTR, START );
         DECLARE ( B$PTR, C$PTR )                 ADDRESS;
         DECLARE ( A, START )                     BYTE;
         DECLARE ( B BASED B$PTR, C BASED C$PTR ) LONG$INTEGER;
         DECLARE ( CDIGIT, D$CARRY, BPOS, CPOS )  BYTE;
         D$CARRY = 0;
         CPOS    = START;
         DO BPOS = 1 TO B( 0 );
            CDIGIT = C( CPOS ) + ( A * B( BPOS ) ) + D$CARRY;
            IF CDIGIT < DIGIT$BASE THEN D$CARRY = 0;
            ELSE DO;
               /* HAVE DIGITS TO CARRY                                      */
               D$CARRY = CDIGIT  /  DIGIT$BASE;
               CDIGIT  = CDIGIT MOD DIGIT$BASE;
            END;
            C( CPOS ) = CDIGIT;
            CPOS = CPOS + 1;
         END;
         C( CPOS ) = D$CARRY;
         /* REMOVE LEADING ZEROS BUT IF THE NUMBER IS 0, KEEP THE FINAL 0   */
         DO WHILE( CPOS > 1 AND C( CPOS ) = 0 );
            CPOS = CPOS - 1;
         END;
         C( 0 ) = CPOS;
      END MULTIPLY$ELEMENT ;
      /* THE RESULT WILL BE COMPUTED IN MRESULT, ALLOWING A OR B TO BE C    */
      DO RPOS = 1 TO LAST( MRESULT ); MRESULT( RPOS ) = 0; END;
      /* MULTIPLY BY EACH DIGIT AND ADD TO THE RESULT                       */
      DO RPOS = 1 TO A( 0 );
         IF A( RPOS ) <> 0 THEN DO;
            CALL MULTIPLY$ELEMENT( A( RPOS ), B$PTR, .MRESULT, RPOS );
         END;
      END;
      /* RETURN THE RESULT IN C                                             */
      DO RPOS = 0 TO MRESULT( 0 ); C( RPOS ) = MRESULT( RPOS ); END;
   END;

   /* INTEGER SUARE ROOT: BASED ON THE ONE IN THE PL/M FOR FROBENIUS NUMBERS */
   SQRT: PROCEDURE( N )ADDRESS;
      DECLARE ( N, X0, X1 ) ADDRESS;
      IF N <= 3 THEN DO;
          IF N = 0 THEN X0 = 0; ELSE X0 = 1;
          END;
      ELSE DO;
         X0 = SHR( N, 1 );
         DO WHILE( ( X1 := SHR( X0 + ( N / X0 ), 1 ) ) < X0 );
            X0 = X1;
         END;
      END;
      RETURN X0;
   END SQRT;

   /* FIND THE PYTHAGORIAN TRIPLET                                          */
   DECLARE ( A, B, C, M, N, M2, N2, SQRT$1000 ) ADDRESS;
   DECLARE ( LA, LB, LC, ABC ) LONG$INTEGER;
   SQRT$1000 = SQRT( 1000 );
   DO N = 1 TO SQRT$1000;             /* M AND N MUST HAD DIFFERENT PARITY, */
      DO M = N + 1 TO SQRT$1000 BY 2;             /* I.E. ONE ODD, ONE EVEN */
         /* NOTE: A = M2 - N2, B = 2MN, C = M2 + N2                         */
         /* A + B + C = M2 - N2 + 2MN + M2 + N2 = 2( M2 + MN ) = 2M( M + N )*/ 
         IF ( M * ( M + N ) ) = 500 THEN DO;
            M2 = M * M;
            N2 = N * N;
            CALL SET$LONG$INTEGER( .A, M2 - N2 );
            CALL SET$LONG$INTEGER( .B, 2 * M * N );
            CALL SET$LONG$INTEGER( .C, M2 + N2 );
            CALL LONG$MULTIPLY( .A,   .B, .ABC );
            CALL LONG$MULTIPLY( .ABC, .C, .ABC );
            CALL PRINT$LONG$INTEGER( .ABC );
            CALL PRINT$NL;
         END;
      END;
   END;

EOF
Output:
31875000

Python

Python 3.8.8 (default, Apr 13 2021, 15:08:03)
Type "help", "copyright", "credits" or "license" for more information.
>>> [(a, b, c) for a in range(1, 1000) for b in range(a, 1000) for c in range(1000) if a + b + c == 1000 and a*a + b*b == c*c]
[(200, 375, 425)]

Raku

hyper for 1..998 -> $a {
    my $a2 = $a²;
    for $a + 1 .. 999 -> $b {
        my $c = 1000 - $a - $b;
        last if $c < $b;
        say "$a² + $b² = $c²\n$a  + $b  + $c = {$a+$b+$c}\n$a  × $b  × $c = {$a×$b×$c}"
            and exit if $a2 + $b² == $c²
    }
}
Output:
200² + 375² = 425²
200  + 375  + 425 = 1000
200  × 375  × 425 = 31875000

REXX

Some optimizations were done such as pre-computing the squares of all possible A's, B's, and C's.

Also, there were multiple shortcuts to limit an otherwise exhaustive search;   Once a sum or a square was too big,
the next integer was used   (for the previous DO loop).

/*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 sum hi n .                             /*obtain optional argument from the CL.*/
if sum=='' | sum==","  then sum= 1000            /*Not specified?  Then use the default.*/
if  hi=='' |  hi==","  then  hi= 1000            /* "      "         "   "   "     "    */
if   n=='' |   n==","  then   n=    1            /* "      "         "   "   "     "    */
hh= hi - 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    for hh%2  by 2;   aa= @.a   /*search for solutions to the equations*/
        do    b=a+1;                   ab= a + b /*compute the sum of 2 numbers (A & B).*/
        if ab>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  while @.c <= aabb           /*test integers that satisfy equations.*/
           if @.c\==aabb  then iterate           /*   "  \=A^2+B^2?  Then keep searching*/
           abc= ab + c                           /*compute the sum of:   A  +  B  +  C  */
           if abc >  sum  then iterate b         /*Is  A+B+C > SUM?  Then stop with C's.*/
           if abc == sum  then call show         /*Does  "   = SUM?  Then solution found*/
           end   /*c*/
        end      /*b*/
     end         /*a*/
done:              if #==0  then #= 'no';  say pad pad pad   #   ' solution's(#)  "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
output   when using the default inputs:
          a= 200           b= 375           c= 425
                              1  solution found.

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.

tf = 1000 # time factor adjustment for different Ring versions

? "working..."

? "turtle method:" # 3 nested loops is not a good approach, 
                   # even when cheating by cherry-picking the loop start/end points...
st = clock()

for a = 100 to 400
     for b = 200 to 800
           for c = b to 1000 - a - b
                 if a + b + c = 1000
                       if a * a + b * b = c * c exit 3 ok
                 ok
           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
st = clock()

for a = 1 to 1000
      for b = a to 1000
            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..."
Output:
working...
turtle method:
a = 200 b = 375 c = 425
Elapsed time = 13.36 s

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...

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) ;
}
Output:
{375, 425, 200}
The product of {375, 425, 200} is 31875000

Wren

Very simple approach, only takes 0.013 seconds even in Wren.

var a = 3
while (true) {
    var b = a + 1
    while (true) {
        var c = 1000 - a - b
        if (c <= b) break
        if (a*a + b*b == c*c) {
            System.print("a = %(a), b = %(b), c = %(c)")
            System.print("a + b + c = %(a + b + c)")
            System.print("a * b * c = %(a * b * c)")
            return
        }
        b = b + 1
    }
    a = a + 1
}
Output:
a = 200, b = 375, c = 425
a + b + c = 1000
a * b * c = 31875000


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:

for (a in 3..332) {
    var b = a + 1
    while (true) {
        var c = 1000 - a - b
        if (c <= b) break
        if (a*a + b*b == c*c) {
            System.print("a = %(a), b = %(b), c = %(c)")
            System.print("a + b + c = %(a + b + c)")
            System.print("a * b * c = %(a * b * c)")
        }
        b = b + 1
    }
}

XPL0

int N, M, A, B, C;
for N:= 1 to sqrt(1000) do
    for M:= N+1 to sqrt(1000) do
        [A:= M*M - N*N; \Euclid's formula
         B:= 2*M*N;
         C:= M*M + N*N;
         if A+B+C = 1000 then
            IntOut(0, A*B*C);
        ]
Output:
31875000