Special pythagorean triplet: Difference between revisions
(→{{header|ALGOL W}}: Make it closer to the Wren original and small optimisations) |
(→{{header|REXX}}: added the computer programming language REXX.) |
||
Line 132: | Line 132: | ||
<pre>200² + 375² = 425² |
<pre>200² + 375² = 425² |
||
200 + 375 + 425 = 1000</pre> |
200 + 375 + 425 = 1000</pre> |
||
=={{header|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 exhausting search; Once a sum or a square was too big, |
|||
<br>the next integer was used. |
|||
<lang rexx>/*REXX pgm computes/shows integers A, B, and C that solve: A+B+C = 1000; A^2+B^2 = C^2*/ |
|||
parse arg s hi . /*obtain optional argument from the CL.*/ |
|||
if s=='' | s=="," then s= 1000 /*Not specified? Then use the default.*/ |
|||
if hi=='' | hi=="," then hi= 1000 /* " " " " " " */ |
|||
do j=1 for hi; @.j= j*j /*precompute squares up to HI. */ |
|||
end /*j*/ |
|||
do a=1 for hi-2; aa= @.a /*go hunting for solutions to equation.*/ |
|||
do b=a+1 to hi-1; ab= a + b /*calculate sum of two (A,B) squares.*/ |
|||
if ab>hi 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 to hi /*handle all ints that satisfy equation*/ |
|||
if @.c > aabb then iterate b /*Square> A^2+B^2? Then stop with C's.*/ |
|||
if @.c\==aabb then iterate /*Square\=A^2+B^2? Then keep searching*/ |
|||
abc= ab + c /*compute the sum of A + B + C */ |
|||
if abc ==s then leave a /*Does A+B+C = S? Then solution found*/ |
|||
if abc > s then iterate b /* " " > S? Then stop with C's.*/ |
|||
end /*c*/ |
|||
end /*b*/ |
|||
end /*a*/ |
|||
say ' a=' a " b=" b ' c=' c |
|||
exit 0 /*stick a fork in it, we're all done. */</lang> |
|||
{{out|output|text= when using the default inputs:}} |
|||
<pre> |
|||
a= 200 b= 375 c= 425 |
|||
</pre> |
|||
=={{header|Ring}}== |
=={{header|Ring}}== |
Revision as of 18:47, 30 August 2021
- Task
- The following problem is taken from Project Euler
- Related task
ALGOL 68
...but doesn't stop on the first solution (thus verifying there is only one). <lang algol68># find the Pythagorian triplet a, b, c where a + b + c = 1000, a < b < c # FOR a TO 1000 OVER 3 DO
INT a2 = a * a; FOR b FROM a + 1 TO 1000 WHILE INT a plus b = a + b; INT c = 1000 - a plus b; c > b DO IF a2 + b*b = c*c THEN print( ( "a = ", whole( a, 0 ), ", b = ", whole( b, 0 ), ", c = ", whole( c, 0 ), newline ) ); print( ( "a + b + c = ", whole( a plus b + c, 0 ), newline ) ); print( ( "a * b * c = ", whole( a * b * c, 0 ), newline ) ) FI OD
OD</lang>
- Output:
a = 200, b = 375, c = 425 a + b + c = 1000 a * b * c = 31875000
ALGOL W
...but doesn't stop on the first solution (thus verifying there is only one). <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; 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 .</lang>
- Output:
a = 200, b = 375, c = 425 a + b + c = 1000 a * b * c = 31875000
Go
<lang go>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 } } }
}</lang>
- Output:
a = 200, b = 375, c = 425 a + b + c = 1000 a * b * c = 31875000 Took 77.664µs
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)
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
<lang perl6>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 = 1000" and exit if $a2 + $b² == $c² }
}</lang>
- Output:
200² + 375² = 425² 200 + 375 + 425 = 1000
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 exhausting search; Once a sum or a square was too big,
the next integer was used.
<lang rexx>/*REXX pgm computes/shows integers A, B, and C that solve: A+B+C = 1000; A^2+B^2 = C^2*/
parse arg s hi . /*obtain optional argument from the CL.*/
if s== | s=="," then s= 1000 /*Not specified? Then use the default.*/
if hi== | hi=="," then hi= 1000 /* " " " " " " */
do j=1 for hi; @.j= j*j /*precompute squares up to HI. */ end /*j*/
do a=1 for hi-2; aa= @.a /*go hunting for solutions to equation.*/ do b=a+1 to hi-1; ab= a + b /*calculate sum of two (A,B) squares.*/ if ab>hi 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 to hi /*handle all ints that satisfy equation*/ if @.c > aabb then iterate b /*Square> A^2+B^2? Then stop with C's.*/ if @.c\==aabb then iterate /*Square\=A^2+B^2? Then keep searching*/ abc= ab + c /*compute the sum of A + B + C */ if abc ==s then leave a /*Does A+B+C = S? Then solution found*/ if abc > s then iterate b /* " " > S? Then stop with C's.*/ end /*c*/ end /*b*/ end /*a*/
say ' a=' a " b=" b ' c=' c exit 0 /*stick a fork in it, we're all done. */</lang>
- output when using the default inputs:
a= 200 b= 375 c= 425
Ring
<lang ring> load "stdlib.ring" see "working..." + nl
time1 = clock() for a = 1 to 1000
for b = a+1 to 1000 for c = b+1 to 1000 if (pow(a,2)+pow(b,2)=pow(c,2)) if a+b+c = 1000 see "a = " + a + " b = " + b + " c = " + c + nl exit 3 ok ok next next
next
time2 = clock() time3 = time2/1000 - time1/1000 see "Elapsed time = " + time3 + " s" + nl see "done..." + nl </lang>
- Output:
working... a = 200 b = 375 c = 425 Elapsed time = 497.61 s done...
Wren
Very simple approach, only takes 0.013 seconds even in Wren. <lang ecmascript>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
}</lang>
- 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:
<lang ecmascript>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 }
}</lang>
XPL0
<lang 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); ]</lang>
- Output:
31875000