RosettaCodeData/Task/Heronian-triangles/Smalltalk/heronian-triangles.st
2023-07-01 13:44:08 -04:00

41 lines
1.4 KiB
Smalltalk

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.