Heronian triangles
Hero's formula for the area of a triangle given the length of its three sides a, b, and c is given by:
where s is half the perimeter of the triangle; that is,
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. this will exclude, for example triangle 6,8,10
The task is to:
- Create a named function/method/proceedure/... 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
Python
<lang python>from math import sqrt from fractions import gcd
def hero(a, b, c):
s = (a + b + c) / 2 a2 = s*(s-a)*(s-b)*(s-c) 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__':
maxside = 200 h = [(a, b, c) for a,b,c in product(range(1, maxside + 1), repeat=3) if a <= b <= c and a + b > c and gcd3(a, b, c) == 1 and is_heronian(a, b, c)] h.sort(key = lambda x: (hero(*x), sum(x), x[::-1])) # By increasing area, perimeter, then sides 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:') 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))</lang>
- Output:
Primitive Heronian triangles with sides up to 200: 517 First ten when ordered by increasing area, then perimeter,then maximum sides: (3, 4, 5) perim: 12 area: 6 (5, 5, 6) perim: 16 area: 12 (5, 5, 8) perim: 18 area: 12 (4, 13, 15) perim: 32 area: 24 (5, 12, 13) perim: 30 area: 30 (9, 10, 17) perim: 36 area: 36 (3, 25, 26) perim: 54 area: 36 (7, 15, 20) perim: 42 area: 42 (10, 13, 13) perim: 36 area: 60 (8, 15, 17) perim: 40 area: 60 All with area 210 subject to the previous ordering: (17, 25, 28) perim: 70 area: 210 (20, 21, 29) perim: 70 area: 210 (12, 35, 37) perim: 84 area: 210 (17, 28, 39) perim: 84 area: 210 (7, 65, 68) perim: 140 area: 210 (3, 148, 149) perim: 300 area: 210