Hero's formula for the area of a triangle given the length of its three sides    a,   b,   and   c   is given by:

 



A
=


s
(
s
−
a
)
(
s
−
b
)
(
s
−
c
)


,


{\displaystyle A={\sqrt {s(s-a)(s-b)(s-c)}},}


where   s   is half the perimeter of the triangle; that is,

 



s
=



a
+
b
+
c

2


.


{\displaystyle s={\frac {a+b+c}{2}}.}



Heronian triangles
are triangles whose sides and area are all integers.

 An example is the triangle with sides   3, 4, 5   whose area is   6   (and whose perimeter is   12). 


Note that any triangle whose sides are all an integer multiple of   3, 4, 5;   such as   6, 8, 10,   will also be a Heronian triangle.

Define a Primitive Heronian triangle as a Heronian triangle where the greatest common divisor
of all three sides is   1   (unity).

This will exclude, for example, triangle   6, 8, 10.



Task

 Create a named function/method/procedure/... that implements Hero's formula.
 Use the function to generate all the primitive Heronian triangles with sides <= 200.
 Show the count of how many triangles are found.
 Order the triangles by first increasing area, then by increasing perimeter, then by increasing maximum side lengths
 Show the first ten ordered triangles in a table of sides, perimeter, and area.
 Show a similar ordered table for those triangles with area = 210


Show all output here.

Note: when generating triangles it may help to restrict 



a
<=
b
<=
c


{\displaystyle a<=b<=c}



perimeter := [:triangle | triangle reduce: #+].
 
squaredArea := [:triangle | 
	| s  |
	s := (perimeter value: triangle) / 2.
	triangle inject: s into: [:a2 :edge | s - edge * a2]].
 
isPrimitive := [:triangle | (triangle reduce: #gcd:) = 1].
 
isHeronian := [:triangle | (squaredArea value: triangle) sqrt isInteger].
 
heroGenerator := Generator on: [:generator |
	1 to: 200 do: [:a |
	a to: 200 do: [:b |
	b to: (a+b-1 min: 200) do: [:c |
		| triangle |
		triangle := {a. b. c.}.
		((isPrimitive value: triangle) and: [isHeronian value: triangle])
			ifTrue: [generator nextPut: triangle]]]]].
 
heronians := heroGenerator contents.
sorter := squaredArea ascending , perimeter ascending , #third ascending , #second ascending , #first ascending.
sorted := heronians sorted: sorter.
area210 := sorted select: [:triangle | (squaredArea value: triangle) = 210 squared].
 
header := [:title |
	Transcript cr; cr; nextPutAll: title; cr.
	#(peri area a b c) do: [:s | Transcript nextPutAll: s; tab]].
tabulate := [:t |
	Transcript cr.
	Transcript print: (perimeter value: t); tab.
	Transcript print: (squaredArea value: t) sqrt.
	t do: [:edge | Transcript tab; print: edge].].
 
Transcript cr; print: heronians size; nextPutAll: ' heronians triangles of side <= 200 where found'.
header value: 'first 10 sorted by area, then perimeter, the largest side'.
(sorted first: 10) do: tabulate.
header value: 'heronians of area 210'.
area210 do: tabulate.
 
Transcript flush.