Special pythagorean triplet

From Rosetta Code
(Redirected from Special Pythagorean Triplet)
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[edit]

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[edit]

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[edit]

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[edit]

# 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++[edit]

#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[edit]

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[edit]

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#[edit]

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[edit]

' 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[edit]

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[edit]

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[edit]

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[edit]

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[edit]

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[edit]

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[edit]

strictly adhering to the task description[edit]

See Empty_program#Phix

brute force (83000 iterations)[edit]

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)[edit]

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[edit]

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[edit]

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[edit]

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[edit]

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[edit]

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

Wren[edit]

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[edit]

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