RosettaCodeData/Task/Heronian-triangles/Python/heronian-triangles.py

45 lines
1.2 KiB
Python
Raw Permalink Normal View History

2015-11-18 06:14:39 +00:00
from __future__ import division, print_function
2019-09-12 10:33:56 -07:00
from math import gcd, sqrt
2015-02-20 09:02:09 -05:00
def hero(a, b, c):
s = (a + b + c) / 2
2019-09-12 10:33:56 -07:00
a2 = s * (s - a) * (s - b) * (s - c)
2015-02-20 09:02:09 -05:00
return sqrt(a2) if a2 > 0 else 0
def is_heronian(a, b, c):
a = hero(a, b, c)
return a > 0 and a.is_integer()
def gcd3(x, y, z):
return gcd(gcd(x, y), z)
if __name__ == '__main__':
2019-09-12 10:33:56 -07:00
MAXSIDE = 200
N = 1 + MAXSIDE
h = [(x, y, z)
for x in range(1, N)
for y in range(x, N)
for z in range(y, N) if (x + y > z) and
1 == gcd3(x, y, z) and
is_heronian(x, y, z)]
# By increasing area, perimeter, then sides
h.sort(key=lambda x: (hero(*x), sum(x), x[::-1]))
print(
'Primitive Heronian triangles with sides up to %i:' % MAXSIDE, len(h)
)
print('\nFirst ten when ordered by increasing area, then perimeter,',
'then maximum sides:')
2015-02-20 09:02:09 -05:00
print('\n'.join(' %14r perim: %3i area: %i'
% (sides, sum(sides), hero(*sides)) for sides in h[:10]))
print('\nAll with area 210 subject to the previous ordering:')
print('\n'.join(' %14r perim: %3i area: %i'
% (sides, sum(sides), hero(*sides)) for sides in h
if hero(*sides) == 210))