Heronian triangles: Difference between revisions

Content added Content deleted
(Added Wren)
(Updated to compile with Nim 1.4. Improved formatting. Replaced module "strfmt" by module "strformat".)
Line 2,991: Line 2,991:


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>import math, algorithm, strfmt, sequtils
<lang nim>import math, algorithm, lenientops, strformat, sequtils


type HeronianTriangle = tuple[a, b, c: int; p: int; area: int]
type
HeronianTriangle = tuple
a: int
b: int
c: int
s: float
A: int


proc `$` (t: HeronianTriangle): string =
func `$` (t: HeronianTriangle): string =
fmt("{:3d}, {:3d}, {:3d}\t{:7.3f}\t{:3d}", t.a, t.b, t.c, t.s, t.A)
fmt"{t.a:3d}, {t.b:3d}, {t.c:3d} {t.p:7d} {t.area:8d}"
proc hero(a:int, b:int, c:int): tuple[s, A: float] =
let s: float = (a + b + c) / 2
result = (s, sqrt( s * (s - float(a)) * (s - float(b)) * (s - float(c)) ))
proc isHeronianTriangle(x: float): bool = ceil(x) == x and x.toInt > 0


proc gcd(x: int, y: int): int =
func hero(a, b, c: int): float =
let s = (a + b + c) / 2
result = sqrt(s * (s - a) * (s - b) * (s - c))

func isHeronianTriangle(x: float): bool = x > 0 and ceil(x) == x

func gcd(x, y: int): int =
var
var
(dividend, divisor) = if x > y: (x, y) else: (y, x)
(dividend, divisor) = if x > y: (x, y) else: (y, x)
remainder = dividend mod divisor
remainder = dividend mod divisor

while remainder != 0:
while remainder != 0:
dividend = divisor
dividend = divisor
Line 3,020: Line 3,014:
remainder = dividend mod divisor
remainder = dividend mod divisor
result = divisor
result = divisor
var list = newSeq[HeronianTriangle]()
const max = 200


func max(a, b, c: int): int = max(a, max(b, c))
for c in 1..max:
func gcd(a, b, c: int): int = gcd(a, gcd(b, c))

const Header = " Sides Perimeter Area\n------------- --------- ----"

var list: seq[HeronianTriangle]
const Max = 200

for c in 1..Max:
for b in 1..c:
for b in 1..c:
for a in 1..b:
for a in 1..b:
let (s, A) = hero(a, b, c)
let area = hero(a, b, c)
if isHeronianTriangle(A) and gcd(a, gcd(b, c)) == 1:
if isHeronianTriangle(area) and gcd(a, b, c) == 1:
let t:HeronianTriangle = (a, b, c, s, A.toInt)
let t: HeronianTriangle = (a, b, c, a + b + c, area.toInt)
list.add(t)
list.add(t)


echo "Numbers of Heronian Triangle : ", list.len
echo "Number of Heronian triangles: ", list.len


list.sort do (x, y: HeronianTriangle) -> int:
list.sort do (x, y: HeronianTriangle) -> int:
result = cmp(x.A, y.A)
result = cmp(x.area, y.area)
if result == 0:
if result == 0:
result = cmp(x.s, y.s)
result = cmp(x.p, y.p)
if result == 0:
if result == 0:
result = cmp(max(x.a, x.b, x.c), max(y.a, y.b, y.c))
result = cmp(max(x.a, x.b, x.c), max(y.a, y.b, y.c))


echo "\nOrdered list of first ten Heronian triangles:"
echo "Ten first Heronian triangle ordered : "
echo Header
echo "Sides Perimeter Area"
for t in list[0 .. <10]:
for t in list[0 ..< 10]: echo t
echo t


echo "Heronian triangle ordered with Area 210 : "
echo "\nOrdered list of Heronian triangles with area 210:"
echo Header
echo "Sides Perimeter Area"
for t in list.filter(proc (x: HeronianTriangle): bool = x.A == 210):
for t in list.filterIt(it.area == 210): echo t
echo t</lang>
</lang>
{{out}}
{{out}}
<pre>Numbers of Heronian Triangle : 517
<pre>Number of Heronian triangles: 517

Ten first Heronian triangle ordered :
Ordered list of first ten Heronian triangles:
Sides Perimeter Area
3, 4, 5 6.000 6
Sides Perimeter Area
------------- --------- ----
5, 5, 6 8.000 12
5, 5, 8 9.000 12
3, 4, 5 12 6
4, 13, 15 16.000 24
5, 5, 6 16 12
5, 12, 13 15.000 30
5, 5, 8 18 12
9, 10, 17 18.000 36
4, 13, 15 32 24
3, 25, 26 27.000 36
5, 12, 13 30 30
7, 15, 20 21.000 42
9, 10, 17 36 36
10, 13, 13 18.000 60
3, 25, 26 54 36
8, 15, 17 20.000 60
7, 15, 20 42 42
10, 13, 13 36 60
Heronian triangle ordered with Area 210 :
Sides Perimeter Area
8, 15, 17 40 60

17, 25, 28 35.000 210
Ordered list of Heronian triangles with area 210:
20, 21, 29 35.000 210
Sides Perimeter Area
12, 35, 37 42.000 210
------------- --------- ----
17, 28, 39 42.000 210
7, 65, 68 70.000 210
17, 25, 28 70 210
20, 21, 29 70 210
3, 148, 149 150.000 210</pre>
12, 35, 37 84 210
17, 28, 39 84 210
7, 65, 68 140 210
3, 148, 149 300 210</pre>


=={{header|ooRexx}}==
=={{header|ooRexx}}==