42 lines
1.4 KiB
ObjectPascal
42 lines
1.4 KiB
ObjectPascal
uses school;
|
|
|
|
function hero(a, b, c: integer): real;
|
|
begin
|
|
var s := (a + b + c) / 2;
|
|
var a2 := s * (s - a) * (s - b) * (s - c);
|
|
result := if a2 > 0 then a2.sqrt else 0;
|
|
end;
|
|
|
|
function is_heronian(a, b, c: integer): boolean;
|
|
begin
|
|
var h := hero(a, b, c);
|
|
result := (h > 0) and (h = h.Ceil);
|
|
end;
|
|
|
|
function gcd3(x, y, z: integer) := gcd(gcd(x, y), z);
|
|
|
|
function heronians(n: integer): sequence of (integer, integer, integer);
|
|
begin
|
|
for var x := 1 to n do
|
|
for var y := x to n do
|
|
for var z := y to n do
|
|
if (x + y > z) and (gcd3(x, y, z) = 1) and is_heronian(x, y, z) then
|
|
yield (x, y, z);
|
|
end;
|
|
|
|
begin
|
|
var n := 200;
|
|
var hsorted := heronians(n).OrderBy(t -> hero(t[0], t[1], t[2]))
|
|
.ThenBy(t -> t[0] + t[1] + t[2])
|
|
.ThenBy(t -> t[2]);
|
|
|
|
writeln('Primitive Heronian triangles with sides up to ', n, ': ', hsorted.count);
|
|
writeln;
|
|
writeln('First ten when ordered by increasing area, then perimeter, then maximum sides:');
|
|
foreach var h in hsorted.Take(10) do
|
|
writeln(h:12, ' perim: ', h[0] + h[1] + h[2]:3, ' area: ', hero(h[0], h[1], h[2]):3);
|
|
writeln;
|
|
writeln('All with area 210 subject to the previous ordering:');
|
|
foreach var h in hsorted.Where(t -> hero(t[0], t[1], t[2]) = 210) do
|
|
writeln(h:12, ' perim: ', h[0] + h[1] + h[2]:3, ' area: ', hero(h[0], h[1], h[2]):3);
|
|
end.
|