Law of cosines - triples: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(→‎{{header|Lua}}: added Lua solution)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(14 intermediate revisions by 11 users not shown)
Line 39:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">-V n = 13
 
F method1(n)
Line 69:
V t60 = method1(10'000)[1]
V notsame = sum(t60.filter((a, b, c) -> a != b | b != c).map((a, b, c) -> 1))
print(‘Extra credit: ’notsame)</langsyntaxhighlight>
 
{{out}}
Line 81:
[(3, 5, 7), (7, 8, 13)]
Extra credit: 18394
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC Test(INT max,angle,coeff)
BYTE count,a,b,c
 
PrintF("gamma=%B degrees:%E",angle)
count=0
FOR a=1 TO max
DO
FOR b=1 TO a
DO
FOR c=1 TO max
DO
IF a*a+b*b-coeff*a*b=c*c THEN
PrintF("(%B,%B,%B) ",a,b,c)
count==+1
FI
OD
OD
OD
PrintF("%Enumber of triangles is %B%E%E",count)
RETURN
 
PROC Main()
Test(13,90,0)
Test(13,60,1)
Test(13,120,-1)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Law_of_cosines_-_triples.png Screenshot from Atari 8-bit computer]
<pre>
gamma=90 degrees:
(4,3,5) (8,6,10) (12,5,13)
number of triangles is 3
 
gamma=60 degrees:
(1,1,1) (2,2,2) (3,3,3) (4,4,4) (5,5,5) (6,6,6) (7,7,7) (8,3,7) (8,5,7) (8,8,8) (9,9,9) (10,10,10) (11,11,11) (12,12,12) (13,13,13)
number of triangles is 15
 
gamma=120 degrees:
(5,3,7) (8,7,13)
number of triangles is 2
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Ada.Containers.Ordered_Maps;
 
Line 153 ⟶ 196:
Count_Triangles;
Extra_Credit (Limit => 10_000);
end Law_Of_Cosines;</langsyntaxhighlight>
 
{{out}}
Line 185 ⟶ 228:
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">BEGIN
# find all integer sided 90, 60 and 120 degree triangles by finding integer solutions for #
# a^2 + b^2 = c^2, a^2 + b^2 - ab = c^2, a^2 + b^2 + ab = c^2 where a, b, c in 1 .. 13 #
Line 232 ⟶ 275:
print triangles( 90 );
print triangles( 120 )
END</langsyntaxhighlight>
{{out}}
<pre>
Line 261 ⟶ 304:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f LAW_OF_COSINES_-_TRIPLES.AWK
# converted from C
Line 295 ⟶ 338:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 331 ⟶ 374:
=={{header|C}}==
=== A brute force algorithm, O(N^3) ===
<syntaxhighlight lang="c">/*
<lang C>/*
* RossetaCode: Law of cosines - triples
*
Line 374 ⟶ 417:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 383 ⟶ 426:
 
=== An algorithm with O(N^2) cost ===
<syntaxhighlight lang="c">/*
<lang C>/*
* RossetaCode: Law of cosines - triples
*
Line 427 ⟶ 470:
return 0;
}
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 438 ⟶ 481:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <cmath>
#include <iostream>
#include <tuple>
Line 514 ⟶ 557:
<< min << " to " << max2 << " where the sides are not all of the same length.\n";
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 531 ⟶ 574:
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using static System.Linq.Enumerable;
Line 573 ⟶ 616:
 
private static bool NotAllTheSameLength((int a, int b, int c) triple) => triple.a != triple.b || triple.a != triple.c;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 604 ⟶ 647:
60 degree triangles in range 1..10000 where not all sides are the same
18394 solutions</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
procedure FindTriples(Memo: TMemo; Max,Angle,Coeff: integer);
var Count,A,B,C: integer;
var S: string;
begin
Memo.Lines.Add(Format('Gamma= %d°',[Angle]));
Count:=0;
S:='';
for A:=1 to Max do
for B:=1 to A do
for C:=1 to Max do
if A*A+B*B-Coeff*A*B=C*C then
begin
Inc(Count);
S:=S+Format('(%d,%d,%d) ',[A,B,C]);
if (Count mod 3)=0 then S:=S+CRLF;
end;
Memo.Lines.Add(Format('Number of triangles = %d',[Count]));
Memo.Lines.Add(S);
end;
 
 
 
procedure LawOfCosines(Memo: TMemo);
begin
FindTriples(Memo,13,90,0);
FindTriples(Memo,13,60,1);
FindTriples(Memo,13,120,-1);
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
Gamma= 90°
Number of triangles = 3
(4,3,5) (8,6,10) (12,5,13)
 
Gamma= 60°
Number of triangles = 15
(1,1,1) (2,2,2) (3,3,3)
(4,4,4) (5,5,5) (6,6,6)
(7,7,7) (8,3,7) (8,5,7)
(8,8,8) (9,9,9) (10,10,10)
(11,11,11) (12,12,12) (13,13,13)
 
Gamma= 120°
Number of triangles = 2
(5,3,7) (8,7,13)
 
Elapsed Time: 9.768 ms.
 
</pre>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: backtrack formatting kernel locals math math.ranges
sequences sets sorting ;
IN: rosetta-code.law-of-cosines
Line 625 ⟶ 728:
[ * + ] 120
[ 2drop 0 - ] 90
[ * - ] 60 [ show-solutions ] 2tri@</langsyntaxhighlight>
{{out}}
<pre>
Line 652 ⟶ 755:
{ 13 13 13 }
}
</pre>
 
=={{header|Fortran}}==
<syntaxhighlight lang="fortran">MODULE LAW_OF_COSINES
IMPLICIT NONE
 
CONTAINS
 
! Calculate the third side of a triangle using the cosine rule
REAL FUNCTION COSINE_SIDE(SIDE_A, SIDE_B, ANGLE)
INTEGER, INTENT(IN) :: SIDE_A, SIDE_B
REAL(8), INTENT(IN) :: ANGLE
COSINE_SIDE = SIDE_A**2 + SIDE_B**2 - 2*SIDE_A*SIDE_B*COS(ANGLE)
COSINE_SIDE = COSINE_SIDE**0.5
END FUNCTION COSINE_SIDE
 
! Convert an angle in degrees to radians
REAL(8) FUNCTION DEG2RAD(ANGLE)
REAL(8), INTENT(IN) :: ANGLE
REAL(8), PARAMETER :: PI = 4.0D0*DATAN(1.D0)
 
DEG2RAD = ANGLE*(PI/180)
END FUNCTION DEG2RAD
 
! Sort an array of integers
FUNCTION INT_SORTED(ARRAY) RESULT(SORTED)
INTEGER, DIMENSION(:), INTENT(IN) :: ARRAY
INTEGER, DIMENSION(SIZE(ARRAY)) :: SORTED, TEMP
INTEGER :: MAX_VAL, DIVIDE
SORTED = ARRAY
TEMP = ARRAY
DIVIDE = SIZE(ARRAY)
 
DO WHILE (DIVIDE .NE. 1)
MAX_VAL = MAXVAL(SORTED(1:DIVIDE))
TEMP(DIVIDE) = MAX_VAL
TEMP(MAXLOC(SORTED(1:DIVIDE))) = SORTED(DIVIDE)
SORTED = TEMP
DIVIDE = DIVIDE - 1
END DO
END FUNCTION INT_SORTED
 
! Append an integer to the end of an array of integers
SUBROUTINE APPEND(ARRAY, ELEMENT)
INTEGER, DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: ARRAY
INTEGER, DIMENSION(:), ALLOCATABLE :: TEMP
INTEGER :: ELEMENT
INTEGER :: I, ISIZE
 
IF (ALLOCATED(ARRAY)) THEN
ISIZE = SIZE(ARRAY)
ALLOCATE(TEMP(ISIZE+1))
 
DO I=1, ISIZE
TEMP(I) = ARRAY(I)
END DO
 
TEMP(ISIZE+1) = ELEMENT
 
DEALLOCATE(ARRAY)
 
CALL MOVE_ALLOC(TEMP, ARRAY)
ELSE
ALLOCATE(ARRAY(1))
ARRAY(1) = ELEMENT
END IF
END SUBROUTINE APPEND
 
! Check if an array of integers contains a subset
LOGICAL FUNCTION CONTAINS_ARR(ARRAY, ELEMENT)
INTEGER, DIMENSION(:), INTENT(IN) :: ARRAY
INTEGER, DIMENSION(:) :: ELEMENT
INTEGER, DIMENSION(SIZE(ELEMENT)) :: TEMP, SORTED_ELEMENT
INTEGER :: I, COUNTER, J
 
COUNTER = 0
 
ELEMENT = INT_SORTED(ELEMENT)
 
DO I=1,SIZE(ARRAY),SIZE(ELEMENT)
TEMP = ARRAY(I:I+SIZE(ELEMENT)-1)
DO J=1,SIZE(ELEMENT)
IF (ELEMENT(J) .EQ. TEMP(J)) THEN
COUNTER = COUNTER + 1
END IF
END DO
 
IF (COUNTER .EQ. SIZE(ELEMENT)) THEN
CONTAINS_ARR = .TRUE.
RETURN
END IF
END DO
 
CONTAINS_ARR = .FALSE.
END FUNCTION CONTAINS_ARR
 
! Count and print cosine triples for the given angle in degrees
INTEGER FUNCTION COSINE_TRIPLES(MIN_NUM, MAX_NUM, ANGLE, PRINT_RESULTS) RESULT(COUNTER)
INTEGER, INTENT(IN) :: MIN_NUM, MAX_NUM
REAL(8), INTENT(IN) :: ANGLE
LOGICAL, INTENT(IN) :: PRINT_RESULTS
INTEGER, DIMENSION(:), ALLOCATABLE :: CANDIDATES
INTEGER, DIMENSION(3) :: CANDIDATE
INTEGER :: A, B
REAL :: C
 
COUNTER = 0
 
DO A = MIN_NUM, MAX_NUM
DO B = MIN_NUM, MAX_NUM
C = COSINE_SIDE(A, B, DEG2RAD(ANGLE))
IF (C .GT. MAX_NUM .OR. MOD(C, 1.) .NE. 0) THEN
CYCLE
END IF
 
CANDIDATE(1) = A
CANDIDATE(2) = B
CANDIDATE(3) = C
IF (.NOT. CONTAINS_ARR(CANDIDATES, CANDIDATE)) THEN
COUNTER = COUNTER + 1
CALL APPEND(CANDIDATES, CANDIDATE(1))
CALL APPEND(CANDIDATES, CANDIDATE(2))
CALL APPEND(CANDIDATES, CANDIDATE(3))
 
IF (PRINT_RESULTS) THEN
WRITE(*,'(A,I0,A,I0,A,I0,A)') " (", CANDIDATE(1), ", ", CANDIDATE(2), ", ", CANDIDATE(3), ")"
END IF
END IF
END DO
END DO
END FUNCTION COSINE_TRIPLES
END MODULE LAW_OF_COSINES
 
! Program prints the cosine triples for the angles 90, 60 and 120 degrees
! by using the cosine rule to find the third side of each candidate and
! checking that this is an integer. Candidates are appended to an array
! after the sides have been sorted into ascending order
! the array is repeatedly checked to ensure there are no duplicates.
PROGRAM LOC
USE LAW_OF_COSINES
 
REAL(8), DIMENSION(3) :: TEST_ANGLES = (/90., 60., 120./)
INTEGER :: I, COUNTER
 
DO I = 1,SIZE(TEST_ANGLES)
WRITE(*, '(F0.0, A)') TEST_ANGLES(I), " degree triangles: "
COUNTER = COSINE_TRIPLES(1, 13, TEST_ANGLES(I), .TRUE.)
WRITE(*,'(A, I0)') "TOTAL: ", COUNTER
WRITE(*,*) NEW_LINE('A')
END DO
 
END PROGRAM LOC</syntaxhighlight>
<pre>
90. degree triangles:
(3, 4, 5)
(5, 12, 13)
(6, 8, 10)
TOTAL: 3
 
 
60. degree triangles:
(1, 1, 1)
(2, 2, 2)
(3, 3, 3)
(3, 7, 8)
(4, 4, 4)
(5, 5, 5)
(6, 6, 6)
(7, 7, 7)
(3, 7, 8)
(8, 8, 8)
(9, 9, 9)
(10, 10, 10)
(11, 11, 11)
(12, 12, 12)
(13, 13, 13)
TOTAL: 15
 
 
120. degree triangles:
(3, 5, 7)
(7, 8, 13)
TOTAL: 2
</pre>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 03-03-2019
' compile with: fbc -s console
 
Line 728 ⟶ 1,018:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> 15: 60 degree triangles
Line 763 ⟶ 1,053:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 836 ⟶ 1,126:
fmt.Print(" For an angle of 60 degrees")
fmt.Println(" there are", len(solutions), "solutions.")
}</langsyntaxhighlight>
 
{{out}}
Line 857 ⟶ 1,147:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Data.Monoid ((<>))
Line 905 ⟶ 1,195:
[120, 90, 60])
putStrLn "60 degrees - uneven triangles of maximum side 10000. Total:"
print $ length $ triangles f60ne 10000</langsyntaxhighlight>
{{Out}}
<pre>Triangles of maximum side 13
Line 941 ⟶ 1,231:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">load 'trig stats'
RHS=: *: NB. right-hand-side of Cosine Law
LHS=: +/@:*:@] - cos@rfd@[ * 2 * */@] NB. Left-hand-side of Cosine Law
Line 950 ⟶ 1,240:
idx=. (RHS oppside) i. x LHS"1 adjsides
adjsides ((#~ idx ~: #) ,. ({~ idx -. #)@]) oppside
)</langsyntaxhighlight>
'''Example:'''
<langsyntaxhighlight lang="j"> 60 90 120 solve&.> 13
+--------+-------+------+
| 1 1 1|3 4 5|3 5 7|
Line 971 ⟶ 1,261:
+--------+-------+------+
60 #@(solve -. _3 ]\ 3 # >:@i.@]) 10000 NB. optional extra credit
18394</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">
public class LawOfCosines {
 
Line 1,019 ⟶ 1,309:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,055 ⟶ 1,345:
 
=={{header|JavaScript}}==
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'use strict';
 
Line 1,184 ⟶ 1,474:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>Triangles of maximum side 13:
Line 1,217 ⟶ 1,507:
18394
[Finished in 3.444s]</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
To save space, we define `squares` as a hash rather than as a JSON array.
<syntaxhighlight lang="jq">def squares(n):
reduce range(1; 1+n) as $i ({}; .[$i*$i|tostring] = $i);
 
# if count, then just count
def solve(angle; maxLen; allowSame; count):
squares(maxLen) as $squares
 
| def qsqrt($n):
$squares[$n|tostring] as $sqrt
| if $sqrt then $sqrt else null end;
 
reduce range(1; maxLen+1) as $a ({};
reduce range($a; maxLen+1) as $b (.;
.lhs = $a*$a + $b*$b
| if angle != 90
then if angle == 60
then .lhs += ( - $a*$b)
elif angle == 120
then .lhs += $a*$b
else "Angle must be 60, 90 or 120 degrees" | error
end
else .
end
| qsqrt(.lhs) as $c
| if $c != null
then if allowSame or $a != $b or $b != $c
then .solutions += if count then 1 else [[$a, $b, $c]] end
else .
end
else .
end
)
)
| .solutions ;
 
def task1($angles):
"For sides in the range [1, 13] where they can all be of the same length:\n",
($angles[]
| . as $angle
| solve($angle; 13; true; false)
| " For an angle of \($angle) degrees, there are \(length) solutions, namely:", .);
 
def task2(degrees; n):
"For sides in the range [1, \(n)] where they cannot ALL be of the same length:",
(solve(degrees; n; false; true)
| " For an angle of \(degrees) degrees, there are \(.) solutions.") ;
 
task1([90, 60, 120]), "", task2(60; 10000)</syntaxhighlight>
{{out}}
<pre>
For sides in the range [1, 13] where they can all be of the same length:
 
For an angle of 90 degrees, there are 3 solutions, namely:
[[3,4,5],[5,12,13],[6,8,10]]
For an angle of 60 degrees, there are 15 solutions, namely:
[[1,1,1],[2,2,2],[3,3,3],[3,8,7],[4,4,4],[5,5,5],[5,8,7],[6,6,6],[7,7,7],[8,8,8],[9,9,9],[10,10,10],[11,11,11],[12,12,12],[13,13,13]]
For an angle of 120 degrees, there are 2 solutions, namely:
[[3,5,7],[7,8,13]]
 
For sides in the range [1, 10000] where they cannot ALL be of the same length:
For an angle of 60 degrees, there are 18394 solutions.
</pre>
 
 
=={{header|Julia}}==
{{trans|zkl}}
<langsyntaxhighlight lang="julia">sqdict(n) = Dict([(x*x, x) for x in 1:n])
numnotsame(arrarr) = sum(map(x -> !all(y -> y == x[1], x), arrarr))
 
Line 1,247 ⟶ 1,607:
println("Angle 120:"); for t in tri120 println(t) end
println("\nFor sizes N through 10000, there are $(numnotsame(filtertriangles(10000)[1])) 60 degree triples with nonequal sides.")
</langsyntaxhighlight> {{output}} <pre>
 
Integer triples for 1 <= side length <= 13:
Line 1,280 ⟶ 1,640:
=={{header|Kotlin}}==
{{trans|Go}}
<langsyntaxhighlight lang="scala">// Version 1.2.70
 
val squares13 = mutableMapOf<Int, Int>()
Line 1,347 ⟶ 1,707:
print(" For an angle of 60 degrees")
println(" there are ${solutions.size} solutions.")
}</langsyntaxhighlight>
 
{{output}}
Line 1,368 ⟶ 1,728:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function solve(angle, maxlen, filter)
local squares, roots, solutions = {}, {}, {}
local cos2 = ({[60]=-1,[90]=0,[120]=1})[angle]
Line 1,392 ⟶ 1,752:
solve(60, 10000, fexcr) -- extra credit
solve(90, 10000, fexcr) -- more extra credit
solve(120, 10000, fexcr) -- even more extra credit</langsyntaxhighlight>
{{out}}
<pre>90° on 1..13 has 3 solutions
Line 1,420 ⟶ 1,780:
90° on 1..10000 has 12471 solutions
120° on 1..10000 has 10374 solutions</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">Solve[{a^2+b^2==c^2,1<=a<=13,1<=b<=13,1<=c<=13,a<=b},{a,b,c},Integers]
Length[%]
Solve[{a^2+b^2-a b==c^2,1<=a<=13,1<=b<=13,1<=c<=13,a<=b},{a,b,c},Integers]
Length[%]
Solve[{a^2+b^2+a b==c^2,1<=a<=13,1<=b<=13,1<=c<=13,a<=b},{a,b,c},Integers]
Length[%]
Solve[{a^2+b^2-a b==c^2,1<=a<=10000,1<=b<=10000,1<=c<=10000,a<=b,a!=b,b!=c,a!=c},{a,b,c},Integers]//Length</syntaxhighlight>
{{out}}
<pre>{{a->3,b->4,c->5},{a->5,b->12,c->13},{a->6,b->8,c->10}}
3
{{a->1,b->1,c->1},{a->2,b->2,c->2},{a->3,b->3,c->3},{a->3,b->8,c->7},{a->4,b->4,c->4},{a->5,b->5,c->5},{a->5,b->8,c->7},{a->6,b->6,c->6},{a->7,b->7,c->7},{a->8,b->8,c->8},{a->9,b->9,c->9},{a->10,b->10,c->10},{a->11,b->11,c->11},{a->12,b->12,c->12},{a->13,b->13,c->13}}
15
{{a->3,b->5,c->7},{a->7,b->8,c->13}}
2
18394</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import strformat
import tables
 
Line 1,480 ⟶ 1,857:
echo "\nFor sides in the range [1, 10000] where they cannot ALL be of the same length:\n"
var solutions = solve(60, 10000, false)
echo fmt" For an angle of 60 degrees there are {len(solutions)} solutions."</langsyntaxhighlight>
 
{{out}}
Line 1,506 ⟶ 1,883:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use utf8;
binmode STDOUT, "utf8:";
use Sort::Naturally;
Line 1,539 ⟶ 1,916:
}
 
printf "Non-equilateral n=10000/60°: %d\n", scalar triples(10000,60);</langsyntaxhighlight>
{{out}}
<pre>Integer triangular triples for sides 1..13:
Line 1,548 ⟶ 1,925:
 
=={{header|Phix}}==
Using a simple flat sequence of 100 million elements (well within the desktop language limits, but beyond JavaScript) proved significantly faster than a dictionary (5x or so).
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence squares = repeat(0,10000*10000)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
for c=1 to 10000 do
<span style="color: #000080;font-style:italic;">--constant lim = iff(platform()=JS?13:10000)</span>
squares[c*c] = c
<span style="color: #008080;">constant</span> <span style="color: #000000;">lim</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10000</span>
end for
<span style="color: #000080;font-style:italic;">--sequence squares = repeat(0,lim*lim)</span>
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">squares</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?{}:</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lim</span><span style="color: #0000FF;">*</span><span style="color: #000000;">lim</span><span style="color: #0000FF;">))</span>
function solve(integer angle, maxlen, bool samelen=true)
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lim</span> <span style="color: #008080;">do</span>
sequence res = {}
<span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">*</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
for a=1 to maxlen do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
integer a2 = a*a
for b=a to maxlen do
<span style="color: #008080;">function</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">angle</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">maxlen</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">samelen</span><span style="color: #0000FF;">=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
integer c2 = a2+b*b
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
if angle!=90 then
<span style="color: #008080;">for</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">maxlen</span> <span style="color: #008080;">do</span>
if angle=60 then c2 -= a*b
<span style="color: #004080;">integer</span> <span style="color: #000000;">a2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">*</span><span style="color: #000000;">a</span>
elsif angle=120 then c2 += a*b
<span style="color: #008080;">for</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">a</span> <span style="color: #008080;">to</span> <span style="color: #000000;">maxlen</span> <span style="color: #008080;">do</span>
else crash("angle must be 60/90/120")
<span style="color: #004080;">integer</span> <span style="color: #000000;">c2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">b</span><span style="color: #0000FF;">*</span><span style="color: #000000;">b</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">angle</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">90</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">angle</span><span style="color: #0000FF;">=</span><span style="color: #000000;">60</span> <span style="color: #008080;">then</span> <span style="color: #000000;">c2</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">*</span><span style="color: #000000;">b</span>
integer c = iff(c2>length(squares)?0:squares[c2])
<span style="color: #008080;">elsif</span> <span style="color: #000000;">angle</span><span style="color: #0000FF;">=</span><span style="color: #000000;">120</span> <span style="color: #008080;">then</span> <span style="color: #000000;">c2</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">*</span><span style="color: #000000;">b</span>
if c!=0 and c<=maxlen then
<span style="color: #008080;">else</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"angle must be 60/90/120"</span><span style="color: #0000FF;">)</span>
if samelen or a!=b or b!=c then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res = append(res,{a,b,c})
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c2</span><span style="color: #0000FF;">])</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">maxlen</span> <span style="color: #008080;">then</span>
end for
<span style="color: #008080;">if</span> <span style="color: #000000;">samelen</span> <span style="color: #008080;">or</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">b</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">c</span> <span style="color: #008080;">then</span>
end for
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">})</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
procedure show(string fmt,sequence res, bool full=true)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,fmt,{length(res),iff(full?sprint(res):"")})
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
puts(1,"Integer triangular triples for sides 1..13:\n")
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">full</span><span style="color: #0000FF;">=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
show("Angle 60 has %2d solutions: %s\n",solve( 60,13))
<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: #000000;">fmt</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">full</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">):</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)})</span>
show("Angle 90 has %2d solutions: %s\n",solve( 90,13))
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
show("Angle 120 has %2d solutions: %s\n",solve(120,13))
show("Non-equilateral angle 60 triangles for sides 1..10000: %d%s\n",solve(60,10000,false),false)</lang>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Integer triangular triples for sides 1..13:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Angle 60 has %2d solutions: %s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">60</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Angle 90 has %2d solutions: %s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span> <span style="color: #000000;">90</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Angle 120 has %2d solutions: %s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">120</span><span style="color: #0000FF;">,</span><span style="color: #000000;">13</span><span style="color: #0000FF;">))</span>
<span style="color: #000080;font-style:italic;">--if platform()!=JS then</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Non-equilateral angle 60 triangles for sides 1..10000: %d%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">60</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">),</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--end if</span>
<!--</syntaxhighlight>-->
{{out}}
<pre style="font-size: 11px">
Line 1,594 ⟶ 1,979:
Non-equilateral angle 60 triangles for sides 1..10000: 18394
</pre>
As noted I had to resort to a little trickery to get that last line to run in JavaScript, should a future version impose stricter bounds checking that will stop working.
 
=={{header|Prolog}}==
{{works with|SWI Prolog}}
<langsyntaxhighlight lang="prolog">find_solutions(Limit, Solutions):-
find_solutions(Limit, Solutions, Limit, []).
 
Line 1,660 ⟶ 2,046:
write_triples(60, Solutions),
write_triples(90, Solutions),
write_triples(120, Solutions).</langsyntaxhighlight>
 
{{out}}
Line 1,676 ⟶ 2,062:
=={{header|Python}}==
===Sets===
<langsyntaxhighlight lang="python">N = 13
 
def method1(N=N):
Line 1,704 ⟶ 2,090:
_, t60, _ = method1(10_000)
notsame = sum(1 for a, b, c in t60 if a != b or b != c)
print('Extra credit:', notsame)</langsyntaxhighlight>
 
{{out}}
Line 1,719 ⟶ 2,105:
A variant Python draft based on dictionaries.
(Test functions are passed as parameters to the main function.)
<langsyntaxhighlight lang="python">from itertools import (starmap)
 
 
Line 1,799 ⟶ 2,185:
 
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Triangles of maximum side 13
Line 1,832 ⟶ 2,218:
60 degrees - uneven triangles of maximum side 10000. Total:
18394</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ dup 1
[ 2dup > while
+ 1 >>
2dup / again ]
drop nip ] is sqrt ( n --> n )
 
[ dup * ] is squared ( n --> n )
 
[ dup sqrt squared = ] is square ( n --> b )
[ say "90 degrees" cr
0 temp put
13 times
[ i^ 1+ dup times
[ i^ 1+ squared
over squared +
dup square
over sqrt 14 < and
iff
[ i^ 1+ echo sp
over echo sp
sqrt echo cr
1 temp tally ]
else drop ]
drop ]
temp take echo
say " solutions" cr cr ] is 90deg ( --> )
 
[ say "60 degrees" cr
0 temp put
13 times
[ i^ 1+ dup times
[ i^ 1+
2dup * dip
[ squared
over squared + ]
- dup square
over sqrt 14 < and
iff
[ i^ 1+ echo sp
over echo sp
sqrt echo cr
1 temp tally ]
else drop ]
drop ]
temp take echo
say " solutions" cr cr ] is 60deg ( --> )
[ say "120 degrees" cr
0 temp put
13 times
[ i^ 1+ dup times
[ i^ 1+
2dup * dip
[ squared
over squared + ]
+ dup square
over sqrt 14 < and
iff
[ i^ 1+ echo sp
over echo sp
sqrt echo cr
1 temp tally ]
else drop ]
drop ]
temp take echo
say " solutions" cr cr ] is 120deg ( --> )
 
90deg 60deg 120deg</syntaxhighlight>
 
{{out}}
 
<pre>90 degrees
3 4 5
6 8 10
5 12 13
3 solutions found
 
60 degrees
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
3 8 7
5 8 7
8 8 8
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
15 solutions
 
120 degrees
3 5 7
7 8 13
2 solutions
</pre>
 
=={{header|R}}==
This looks a bit messy, but it really pays off when you see how nicely the output prints.
<syntaxhighlight lang="rsplus">inputs <- cbind(combn(1:13, 2), rbind(seq_len(13), seq_len(13)))
inputs <- cbind(A = inputs[1, ], B = inputs[2, ])[sort.list(inputs[1, ]),]
Pythagoras <- inputs[, "A"]^2 + inputs[, "B"]^2
AtimesB <- inputs[, "A"] * inputs[, "B"]
CValues <- sqrt(cbind("C (90º)" = Pythagoras,
"C (60º)" = Pythagoras - AtimesB,
"C (120º)" = Pythagoras + AtimesB))
CValues[!t(apply(CValues, MARGIN = 1, function(x) x %in% 1:13))] <- NA
output <- cbind(inputs, CValues)[!apply(CValues, MARGIN = 1, function(x) all(is.na(x))),]
rownames(output) <- paste0("Solution ", seq_len(nrow(output)), ":")
print(output, na.print = "")
cat("There are",
sum(!is.na(output[, 3])), "solutions in the 90º case,",
sum(!is.na(output[, 4])), "solutions in the 60º case, and",
sum(!is.na(output[, 5])), "solutions in the 120º case.")</syntaxhighlight>
{{out}}
<pre> A B C (90º) C (60º) C (120º)
Solution 1: 1 1 1
Solution 2: 2 2 2
Solution 3: 3 4 5
Solution 4: 3 5 7
Solution 5: 3 8 7
Solution 6: 3 3 3
Solution 7: 4 4 4
Solution 8: 5 8 7
Solution 9: 5 12 13
Solution 10: 5 5 5
Solution 11: 6 8 10
Solution 12: 6 6 6
Solution 13: 7 8 13
Solution 14: 7 7 7
Solution 15: 8 8 8
Solution 16: 9 9 9
Solution 17: 10 10 10
Solution 18: 11 11 11
Solution 19: 12 12 12
Solution 20: 13 13 13
There are 3 solutions in the 90º case, 15 solutions in the 60º case, and 2 solutions in the 120º case.</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
In each routine, <tt>race</tt> is used to allow concurrent operations, requiring the use of the atomic increment operator, <tt>⚛++</tt>, to safely update <tt>@triples</tt>, which must be declared fixed-sized, as an auto-resizing array is not thread-safe. At exit, default values in <tt>@triples</tt> are filtered out with the test <code>!eqv Any</code>.
<syntaxhighlight lang="raku" perl6line>multi triples (60, $n) {
my %sq = (1..$n).map: { .² => $_ };
my atomicint $i = 0;
Line 1,887 ⟶ 2,418:
my ($angle, $count) = 60, 10_000;
say "\nExtra credit:";
say "$angle° integer triples in the range 1..$count where the sides are not all the same length: ", +triples($angle, $count);</langsyntaxhighlight>
{{out}}
<pre>Integer triangular triples for sides 1..13:
Line 1,917 ⟶ 2,448:
displayed &nbsp; (using the
<br>absolute value of the negative number).
<langsyntaxhighlight lang="rexx">/*REXX pgm finds integer sided triangles that satisfy Law of cosines for 60º, 90º, 120º.*/
parse arg os1 os2 os3 os4 . /*obtain optional arguments from the CL*/
if os1=='' | os1=="," then os1= 13; s1=abs(os1) /*Not specified? Then use the default.*/
Line 1,976 ⟶ 2,507:
end /*b*/
end /*a*/
call foot s4; return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default number of sides for the input: &nbsp; &nbsp; <tt> 13 </tt>}}
<pre>
Line 2,014 ⟶ 2,545:
══════════════════════════ 60º unique ══════════════════════════
18,394 solutions found for 60º unique (sides up to 10,000)
</pre>
 
=={{header|RPL}}==
{{works with|HP|28}}
≪ → formula max
≪ { }
1 max '''FOR''' a a max '''FOR''' b
formula EVAL √ RND
'''IF''' DUP max ≤ OVER FP NOT AND
'''THEN''' a b ROT 3 →LIST 1 →LIST +
'''ELSE''' DROP '''END'''
'''NEXT NEXT'''
≫ ≫ ‘<span style="color:blue">TASK</span>’ STO
 
'a^2+b^2' 13 <span style="color:blue">TASK</span>
'a^2+b^2-a*b' 13 <span style="color:blue">TASK</span>
'a^2+b^2+a*b' 13 <span style="color:blue">TASK</span>
{{out}}
<pre>
3: { { 4 3 5 } { 8 6 10 } { 12 5 13 } }
2: { { 1 1 1 } { 2 2 2 } { 3 3 3 } { 4 4 4 } { 5 5 5 } { 6 6 6 } { 7 7 7 } { 8 3 7 } { 8 5 7 } { 8 8 8 } { 9 9 9 } { 10 10 10 } { 11 11 11 } { 12 12 12 } { 13 13 13 } }
1: { { 5 3 7 } { 8 7 13 } }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">grouped = (1..13).to_a.repeated_permutation(3).group_by do |a,b,c|
sumaabb, ab = a*a + b*b, a*b
case c*c
Line 2,033 ⟶ 2,586:
puts v.inspect, "\n"
end
</syntaxhighlight>
</lang>
{{out}}
<pre>For an angle of 60 there are 15 solutions:
Line 2,045 ⟶ 2,598:
</pre>
Extra credit:
<langsyntaxhighlight lang="ruby">n = 10_000
ar = (1..n).to_a
squares = {}
Line 2,052 ⟶ 2,605:
 
puts "There are #{count} 60° triangles with unequal sides of max size #{n}."
</syntaxhighlight>
</lang>
{{out}}
<pre>There are 18394 60° triangles with unequal sides of max size 10000.
Line 2,060 ⟶ 2,613:
=={{header|Wren}}==
{{trans|Go}}
<langsyntaxhighlight ecmascriptlang="wren">var squares13 = {}
var squares10000 = {}
 
Line 2,120 ⟶ 2,673:
solutions = solve.call(60, 10000, false)
System.write(" For an angle of 60 degrees")
System.print(" there are %(solutions.count) solutions.")</langsyntaxhighlight>
 
{{out}}
Line 2,138 ⟶ 2,691:
 
For an angle of 60 degrees there are 18394 solutions.
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">proc LawCos(Eqn);
int Eqn;
int Cnt, A, B, C;
 
proc Show;
[Cnt:= Cnt+1;
IntOut(0, A); ChOut(0, ^ );
IntOut(0, B); ChOut(0, ^ );
IntOut(0, C); CrLf(0);
];
 
[Cnt:= 0;
for A:= 1 to 13 do
for B:= 1 to A do
for C:= 1 to 13 do
case Eqn of
1: if A*A + B*B = C*C then Show;
2: if A*A + B*B - A*B = C*C then Show;
3: if A*A + B*B + A*B = C*C then Show
other [];
IntOut(0, Cnt); Text(0, " results^m^j");
];
 
proc ExtraCredit;
int Cnt, A, B, C, C2;
[Cnt:= 0;
for A:= 1 to 10_000 do
for B:= 1 to A-1 do
[C2:= A*A + B*B - A*B;
C:= sqrt(C2);
if C*C = C2 then Cnt:= Cnt+1;
];
Text(0, "Extra credit: ");
IntOut(0, Cnt);
CrLf(0);
];
 
int Case;
[for Case:= 1 to 3 do LawCos(Case);
ExtraCredit;
]</syntaxhighlight>
 
{{out}}
<pre>
4 3 5
8 6 10
12 5 13
3 results
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 3 7
8 5 7
8 8 8
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
15 results
5 3 7
8 7 13
2 results
Extra credit: 18394
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn tritri(N=13){
sqrset:=[0..N].pump(Dictionary().add.fp1(True),fcn(n){ n*n });
tri90, tri60, tri120 := List(),List(),List();
Line 2,161 ⟶ 2,785:
tri.sort(fcn(t1,t2){ t1[0]<t2[0] })
.apply("concat",",").apply("(%s)".fmt).concat(",")
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">N:=13;
println("Integer triangular triples for sides 1..%d:".fmt(N));
foreach angle, triples in (T(60,90,120).zip(tritri(N))){
println(" %3d\U00B0; has %d solutions:\n %s"
.fmt(angle,triples.len(),triToStr(triples)));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,179 ⟶ 2,803:
</pre>
Extra credit:
<langsyntaxhighlight lang="zkl">fcn tri60(N){ // special case 60*
sqrset:=[1..N].pump(Dictionary().add.fp1(True),fcn(n){ n*n });
n60:=0;
Line 2,187 ⟶ 2,811:
}
n60
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">N:=10_000;
println(("60\U00b0; triangle where side lengths are unique,\n"
" side lengths 1..%,d, there are %,d solutions.").fmt(N,tri60(N)));</langsyntaxhighlight>
{{out}}
<pre>
9,485

edits