Law of cosines - triples: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added Prolog Solution)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(24 intermediate revisions by 16 users not shown)
Line 35:
* [https://youtu.be/p-0SOWbzUYI?t=12m11s Visualising Pythagoras: ultimate proofs and crazy contortions] Mathlogger Video
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">-V n = 13
 
F method1(n)
V squares = (0..n).map(x -> x ^ 2)
V sqrset = Set(squares)
Set[(Int, Int, Int)] tri90, tri60, tri120
 
L(a) 1..n
V a2 = squares[a]
L(b) 1..a
V b2 = squares[b]
V c2 = a2 + b2
I c2 C sqrset
tri90.add(tuple_sorted((a, b, Int(sqrt(c2)))))
V ab = a * b
c2 -= ab
I c2 C sqrset
tri60.add(tuple_sorted((a, b, Int(sqrt(c2)))))
c2 += 2 * ab
I c2 C sqrset
tri120.add(tuple_sorted((a, b, Int(sqrt(c2)))))
R [sorted(Array(tri90)),
sorted(Array(tri60)),
sorted(Array(tri120))]
 
print(‘Integer triangular triples for sides 1..#.:’.format(n))
L(angle, triples) zip([90, 60, 120], method1(n))
print(" #3° has #. solutions:\n #.".format(angle, triples.len, triples))
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)</syntaxhighlight>
 
{{out}}
<pre>
Integer triangular triples for sides 1..13:
90° has 3 solutions:
[(3, 4, 5), (5, 12, 13), (6, 8, 10)]
60° has 15 solutions:
[(1, 1, 1), (2, 2, 2), (3, 3, 3), (3, 7, 8), (4, 4, 4), (5, 5, 5), (5, 7, 8), (6, 6, 6), (7, 7, 7), (8, 8, 8), (9, 9, 9), (10, 10, 10), (11, 11, 11), (12, 12, 12), (13, 13, 13)]
120° has 2 solutions:
[(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 106 ⟶ 196:
Count_Triangles;
Extra_Credit (Limit => 10_000);
end Law_Of_Cosines;</langsyntaxhighlight>
 
{{out}}
Line 138 ⟶ 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 185 ⟶ 275:
print triangles( 90 );
print triangles( 120 )
END</langsyntaxhighlight>
{{out}}
<pre>
Line 214 ⟶ 304:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f LAW_OF_COSINES_-_TRIPLES.AWK
# converted from C
Line 248 ⟶ 338:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 284 ⟶ 374:
=={{header|C}}==
=== A brute force algorithm, O(N^3) ===
<syntaxhighlight lang="c">/*
<lang C>/*
* RossetaCode: Law of cosines - triples
*
Line 327 ⟶ 417:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 336 ⟶ 426:
 
=== An algorithm with O(N^2) cost ===
<syntaxhighlight lang="c">/*
<lang C>/*
* RossetaCode: Law of cosines - triples
*
Line 380 ⟶ 470:
return 0;
}
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 391 ⟶ 481:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <cmath>
#include <iostream>
#include <tuple>
Line 467 ⟶ 557:
<< min << " to " << max2 << " where the sides are not all of the same length.\n";
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 481 ⟶ 571:
 
There are 18394 solutions for gamma = 60 degrees in the range 1 to 10000 where the sides are not all of the same length.
</pre>
 
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using static System.Linq.Enumerable;
 
public static class LawOfCosinesTriples
{
public static void Main2() {
PrintTriples(60, 13);
PrintTriples(90, 13);
PrintTriples(120, 13);
PrintTriples(60, 10_000, true, false);
}
 
private static void PrintTriples(int degrees, int maxSideLength, bool notAllTheSameLength = false, bool print = true) {
string s = $"{degrees} degree triangles in range 1..{maxSideLength}";
if (notAllTheSameLength) s += " where not all sides are the same";
Console.WriteLine(s);
int count = 0;
var triples = FindTriples(degrees, maxSideLength);
if (notAllTheSameLength) triples = triples.Where(NotAllTheSameLength);
foreach (var triple in triples) {
count++;
if (print) Console.WriteLine(triple);
}
Console.WriteLine($"{count} solutions");
}
 
private static IEnumerable<(int a, int b, int c)> FindTriples(int degrees, int maxSideLength) {
double radians = degrees * Math.PI / 180;
int coefficient = (int)Math.Round(Math.Cos(radians) * -2, MidpointRounding.AwayFromZero);
int maxSideLengthSquared = maxSideLength * maxSideLength;
return
from a in Range(1, maxSideLength)
from b in Range(1, a)
let cc = a * a + b * b + a * b * coefficient
where cc <= maxSideLengthSquared
let c = (int)Math.Sqrt(cc)
where c * c == cc
select (a, b, c);
}
 
private static bool NotAllTheSameLength((int a, int b, int c) triple) => triple.a != triple.b || triple.a != triple.c;
}</syntaxhighlight>
{{out}}
<pre>
60 degree triangles in range 1..13
(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 solutions
90 degree triangles in range 1..13
(4, 3, 5)
(8, 6, 10)
(12, 5, 13)
3 solutions
120 degree triangles in range 1..13
(5, 3, 7)
(8, 7, 13)
2 solutions
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 503 ⟶ 728:
[ * + ] 120
[ 2drop 0 - ] 90
[ * - ] 60 [ show-solutions ] 2tri@</langsyntaxhighlight>
{{out}}
<pre>
Line 530 ⟶ 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 606 ⟶ 1,018:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre> 15: 60 degree triangles
Line 641 ⟶ 1,053:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 714 ⟶ 1,126:
fmt.Print(" For an angle of 60 degrees")
fmt.Println(" there are", len(solutions), "solutions.")
}</langsyntaxhighlight>
 
{{out}}
Line 735 ⟶ 1,147:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Data.Monoid ((<>))
Line 783 ⟶ 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 819 ⟶ 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 828 ⟶ 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 849 ⟶ 1,261:
+--------+-------+------+
60 #@(solve -. _3 ]\ 3 # >:@i.@]) 10000 NB. optional extra credit
18394</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">
public class LawOfCosines {
 
Line 897 ⟶ 1,309:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 933 ⟶ 1,345:
 
=={{header|JavaScript}}==
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'use strict';
 
Line 1,062 ⟶ 1,474:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>Triangles of maximum side 13:
Line 1,095 ⟶ 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,125 ⟶ 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,158 ⟶ 1,640:
=={{header|Kotlin}}==
{{trans|Go}}
<langsyntaxhighlight lang="scala">// Version 1.2.70
 
val squares13 = mutableMapOf<Int, Int>()
Line 1,225 ⟶ 1,707:
print(" For an angle of 60 degrees")
println(" there are ${solutions.size} solutions.")
}</langsyntaxhighlight>
 
{{output}}
Line 1,244 ⟶ 1,726:
For an angle of 60 degrees there are 18394 solutions.
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function solve(angle, maxlen, filter)
local squares, roots, solutions = {}, {}, {}
local cos2 = ({[60]=-1,[90]=0,[120]=1})[angle]
for i = 1, maxlen do squares[i], roots[i^2] = i^2, i end
for a = 1, maxlen do
for b = a, maxlen do
local lhs = squares[a] + squares[b] + cos2*a*b
local c = roots[lhs]
if c and (not filter or filter(a,b,c)) then
solutions[#solutions+1] = {a=a,b=b,c=c}
end
end
end
print(angle.."° on 1.."..maxlen.." has "..#solutions.." solutions")
if not filter then
for i,v in ipairs(solutions) do print("",v.a,v.b,v.c) end
end
end
solve(90, 13)
solve(60, 13)
solve(120, 13)
function fexcr(a,b,c) return a~=b or b~=c end
solve(60, 10000, fexcr) -- extra credit
solve(90, 10000, fexcr) -- more extra credit
solve(120, 10000, fexcr) -- even more extra credit</syntaxhighlight>
{{out}}
<pre>90° on 1..13 has 3 solutions
3 4 5
5 12 13
6 8 10
60° on 1..13 has 15 solutions
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
120° on 1..13 has 2 solutions
3 5 7
7 8 13
60° on 1..10000 has 18394 solutions
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,304 ⟶ 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,330 ⟶ 1,883:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use utf8;
binmode STDOUT, "utf8:";
use Sort::Naturally;
Line 1,363 ⟶ 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,372 ⟶ 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,418 ⟶ 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,484 ⟶ 2,046:
write_triples(60, Solutions),
write_triples(90, Solutions),
write_triples(120, Solutions).</langsyntaxhighlight>
 
{{out}}
Line 1,500 ⟶ 2,062:
=={{header|Python}}==
===Sets===
<langsyntaxhighlight lang="python">N = 13
 
def method1(N=N):
Line 1,528 ⟶ 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,543 ⟶ 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,623 ⟶ 2,185:
 
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Triangles of maximum side 13
Line 1,656 ⟶ 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,706 ⟶ 2,413:
my @itt = triples($angle, $n);
if $angle == 60 { push @itt, "$_ $_ $_" for 1..$n }
printf "Angle %3d° has %2d solutions: %s\n", $angle, +@itt, @itt.sort(*.&naturally).join(', ');
}
 
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,722 ⟶ 2,429:
 
=={{header|REXX}}==
===using(Using some optimization=== and memoization.)
 
Instead of coding a general purpose subroutine (or function) to solve all of the
task's requirements, &nbsp; it was decided to
Line 1,740 ⟶ 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 s1os1 s2os2 s3os3 os4 . /*obtain optional arguments from the CL*/
if s1os1=='' | s1os1=="," then s1os1= 13; s1=abs(os1) /*Not specified? Then use the default.*/
if s2os2=='' | s2os2=="," then s2os2= 13; s2=abs(os2) /* " " " " " " */
if s3os3=='' | s3os3=="," then s3os3= 13; s3=abs(os3) /* " " " " " " */
if os4=='' | os4=="," then os4= -0; s4=abs(os4) /* " " " " " " */
w= max( length(s1), length(s2), length(s3) ) /*W is used to align the side lengths.*/
@.= /*@: array holds squares, max of sides*/
 
if s1>0 then do; call head 120 do j=1 for max(s1, s2, s3, s4); @.j= j /*────120º: j + + ab ≡ c²/*use memoization.*/
end do a=1 for s1; aa = a/*j*a/
if s1>0 then call s1 /*handle the triangle docase for b=a+1 to s1; x= aa + b*b +120º. a*b/
if s2>0 then call s2 /*handle the triangle case for do c=b+1 to90º. s1 until c*c>x/
if s3>0 then call s3 if x==c/*chandle the thentriangle do;case for call show; iterate60º. b; end*/
if s4>0 then call s4 /*handle the case for unique sides. end /*c*/
exit 0 end /*bstick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
end /*a*/
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
call foot s1
dAng: w= length(s); ang= ' 'd"º " uq' '; ss= s * s; @sol= " solutions found for"; return
end
foot: say right(commas(#) @sol ang "(sides up to" commas(arg(1) +0)')', 65); say; return
 
head: #= 0; parse arg d,uq,s; @= ','; call dAng; say center(ang, 65, '═'); return
if s2>0 then do; call head 90 /*────90º: a² + b² ≡ c² */
show: #=#+1; arg p; if p>0 then say ' ('right(a,w)@ right(b,w)@ right(c,w)")"; return
do a=1 for s2; aa = a*a
/*──────────────────────────────────────────────────────────────────────────────────────*/
do b=a+1 to s2; x= aa + b*b
s1: call head 120,,s1 /*────────── 120º: + do c=b+1 ab to s2 until c*c>x/
do a=1 for s1; if xap1==c*c a then do; call show; iterate b; + end1
do b=ap1 for s1-ap1+1; x= @.a + @.b + a*b; if x>ss then enditerate /*c*/a
do c=b+1 for s1-b+1 until end /*b*/@.c>x
if x==@.c then do; call show os1; iterate b; end /*a*/
end call foot s2/*c*/
end /*b*/
end /*a*/
 
if s3>0 then do; call head 60 foot s1; /*────60º: + ab */return
/*──────────────────────────────────────────────────────────────────────────────────────*/
do a=1 for s3; aa = a*a
s2: call head 90,,s2 /*────────── 90º: do + b=a² to s3; x= aa + b*b - a*b/
do a=1 for s2; ap1= do c=a + to s3 until c*c>x1
do b=ap1 for s2-ap1+1; x= @.a + @.b; if x==c*c>ss then do; call show; iterate b; enda
do c=b+1 for s2-b+2 until end /*@.c*/>x
if x==@.c then do; call show os2; iterate b; end /*b*/
end /*ac*/
end call foot s3/*b*/
end /*a*/
exit call foot s2; /*stick a fork in it, we're all done. */return
/*──────────────────────────────────────────────────────────────────────────────────────*/
s3: call head 60,,s3 /*────────── 60º: a² + b² ─ ab ≡ c² */
do a=1 for s3; s3ma= s3 - a + 1
do b=a for s3ma; x= @.a + @.b - a*b; if x>ss then iterate a
do c=a for s3ma until @.c>x
if x==@.c then do; call show os3; iterate b; end
end /*c*/
end /*b*/
end /*a*/
call foot s2; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
s4: call head 60, 'unique', os4 /*────────── 60º: a² + b² ─ ab ≡ c² */
foot: say right(# ' solutions found for' angle "(sides up to" arg(1)')', 65); say; return
head: #= 0; parse arg deg; angle do a=1 ' 'deg"º " for s4; say center(angle, 65, '═') ap1= a + 1; s4map1= s4 - ap1 + return1
show: #= # + 1; say ' ('right(a, w)"," do right(b,=ap1 w)"," for s4map1; right(c, w)')' x= @.a + @.b - a*b; if return</langx>ss then iterate a
do c=ap1 for s4map1 until @.c>x
if x==@.c then do; call show os4; iterate b; end
end /*c*/
end /*b*/
end /*a*/
call foot s4; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default number of sides for the input: &nbsp; &nbsp; <tt> 13 </tt>}}
<pre>
Line 1,815 ⟶ 2,539:
15 solutions found for 60º (sides up to 13)
</pre>
{{out|output|text= &nbsp; when using the inputs of: &nbsp; &nbsp; <tt> 0 &nbsp; 0 &nbsp; 0 &nbsp; -10000 </tt>}}
 
Note that the first three computations are bypassed because of the three zero ('''0''') numbers, &nbsp; the negative ten thousand indicates to find all the triangles with sides <u>up</u> to 10,000, &nbsp; but not list the triangles, it just reports the &nbsp; ''number'' &nbsp; of solutions found.
===using memoization===
<pre>
<lang rexx>/*REXX pgm finds integer sided triangles that satisfy Law of cosines for 60º, 90º, 120º.*/
══════════════════════════ 60º unique ══════════════════════════
parse arg s1 s2 s3 s4 . /*obtain optional arguments from the CL*/
18,394 solutions found for 60º unique (sides up to 10,000)
if s1=='' | s1=="," then s1= 13 /*Not specified? Then use the default.*/
</pre>
if s2=='' | s2=="," then s2= 13 /* " " " " " " */
if s3=='' | s3=="," then s3= 13 /* " " " " " " */
if s4=='' | s4=="," then s4= -10000 /* " " " " " " */
parse value s1 s2 s3 s4 with os1 os2 os3 os4 . /*obtain the original values for sides.*/
s1=abs(s1); s2=abs(s2); s3=abs(s3); s4=abs(s4) /*use absolute values for the # sides. */
@.=
do j=1 for max(s1, s2, s3, s4); @.j = j*j
end /*j*/ /*build memoization array for squaring.*/
 
=={{header|RPL}}==
if s1>0 then do; call head 120,,os1 /*────120º: a² + b² + ab ≡ c² */
{{works with|HP|28}}
do a=1 for s1
≪ → formula max
do b=a+1 to s1; x= @.a + @.b + a*b
≪ { }
if x>z then iterate a
1 max '''FOR''' a a max '''FOR''' b
do c=b+1 to s1 until @.c>x
formula EVAL √ RND
if x==@.c then do; call show; iterate b; end
'''IF''' DUP max OVER FP NOT AND end /*c*/
'''THEN''' a b ROT 3 →LIST 1 →LIST + end /*b*/
'''ELSE''' DROP '''END'''
end /*a*/
'''NEXT call foot s1NEXT'''
≫ ≫ ‘<span style="color:blue">TASK</span>’ STO
end
 
'a^2+b^2' 13 <span style="color:blue">TASK</span>
if s2>0 then do; call head 90,, os2 /*────90º: a² + b² ≡ c² */
'a^2+b^2-a*b' 13 <span style="color:blue">TASK</span>
do a=1 for s2
'a^2+b^2+a*b' 13 <span style="color:blue">TASK</span>
do b=a+1 to s2; x= @.a + @.b
{{out}}
if x>z then iterate a
do c=b+1 to s2 until @.c>x
if x==@.c then do; call show; iterate b; end
end /*c*/
end /*b*/
end /*a*/
call foot s2
end
 
if s3>0 then do; call head 60,, os3 /*────60º: a² + b² ─ ab ≡ c² */
do a=1 for s3
do b=a to s3; x= @.a + @.b - a*b
if x>z then iterate a
do c=a to s3 until @.c>x
if x==@.c then do; call show; iterate b; end
end /*c*/
end /*b*/
end /*a*/
call foot s3
end
 
if s4>0 then do; call head 60, 'unique', os4 /*────60º: a² + b² ─ ab ≡ c² */
do a=1 for s4
do b=a to s4; x= @.a + @.b - a*b
if x>z then iterate a
do c=a to s4 until @.c>x
if x==@.c then do; if a==b&a==c then iterate b
call show; iterate b
end
end /*c*/
end /*b*/
end /*a*/
call foot s4
end
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
foot: say right(# ' solutions found for' ang "(sides up to" arg(1)')', 65); say; return
head: #=0; arg d,,s;z=s*s;w=length(s); ang=' 'd"º " arg(2); say center(ang,65,'═'); return
show: #= # + 1; if s>0 then say ' ('right(a,w)"," right(b,w)"," right(c,w)')'; return</lang>
{{out|output|text= &nbsp; when using the inputs of: &nbsp; &nbsp; <tt> 0 &nbsp; 0 &nbsp; 0 &nbsp; -10000 </tt>}}
 
Note that the first three computations are bypassed because of the three zero ('''0''') numbers, &nbsp; the negative ten thousand indicates to find all the triangles with sides up to 10,000, &nbsp; but not list the triangles, it just reports the &nbsp; ''number'' &nbsp; of triangles found.
<pre>
3: { { 4 3 5 } { 8 6 10 } { 12 5 13 } }
══════════════════════════ 60º unique═══════════════════════════
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 } }
18394 solutions found for 60º unique (sides up to 10000)
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 1,908 ⟶ 2,586:
puts v.inspect, "\n"
end
</syntaxhighlight>
</lang>
{{out}}
<pre>For an angle of 60 there are 15 solutions:
Line 1,920 ⟶ 2,598:
</pre>
Extra credit:
<langsyntaxhighlight lang="ruby">n = 10_000
ar = (1..n).to_a
squares = {}
Line 1,927 ⟶ 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 1,935 ⟶ 2,613:
=={{header|Wren}}==
{{trans|Go}}
<langsyntaxhighlight ecmascriptlang="wren">var squares13 = {}
var squares10000 = {}
 
Line 1,995 ⟶ 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,013 ⟶ 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,036 ⟶ 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,054 ⟶ 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,062 ⟶ 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,484

edits