Ir al contenido principal

Triángulos de Herón

Un triángulo de Herón es un triángulo tal que sus lados y su área son números enteros. Su nombre se debe al matemático griego Herón de Alejandría que descubrió la fórmula para calcular el área de un triángulo a partir de sus lados.

La fórmula de Herón dice que el área de un triángulo cuyos lados miden a, b y c es \[\sqrt{s(s-a)(s-b)(s-c)}\] donde s es el semiperímetro del triángulo; es decir, \[s=\frac{a+b+c}{2}\]

Un ejemplo de triángulo de Herón es el triángulo de lados 3, 4 y 5 cuya área es 6. Se puede observar que cualquier triángulo cuyos lados sean múltiplos de 3, 4 y 5 también es de Herón; por ejemplo, el de lados 6, 8 y 10 también lo es.

Se dice que un triángulo de Herón es primitivo si el máximo común divisor de sus lados es 1. Por ejemplo, el de lados 3, 4 y 5 es primitivo; pero el de lados 6, 8 y 10 no lo es.

Definir la sucesión

triangulosHeronPrimitivos :: [(Int,Int,Int)]

tal que sus elementos son los triángulos de Herón primitivos ordenados por su perímetro. Por ejemplo,

λ> take 7 triangulosHeronPrimitivos
[(3,4,5),(5,5,6),(5,5,8),(5,12,13),(4,13,15),(10,13,13),(9,10,17)]

Soluciones

triangulosHeronPrimitivos :: [(Int,Int,Int)]
triangulosHeronPrimitivos =
    [(a,b,c) | n <- [3..],
               c <- [1..n],
               b <- [1..c],
               let a = n-b-c,
               0 < a, a <= b,
               esTrianguloHeronPrimitivo a b c]

-- (esTrianguloHeronPrimitivo a b c) se verifica si a, b y c
-- (con a <= b <= c) son los lados de un triángulo de Herón
-- primitivo. Por ejemplo,
--    esTrianguloHeronPrimitivo 3 4  5  ==  True
--    esTrianguloHeronPrimitivo 1 1  2  ==  False
--    esTrianguloHeronPrimitivo 6 8 10  ==  False
esTrianguloHeronPrimitivo :: Int -> Int -> Int -> Bool
esTrianguloHeronPrimitivo a b c =
    esTriangulo a b c &&
    mcd a b c == 1 &&
    p `mod` 2 == 0 &&
    esCuadrado (s*(s-a)*(s-b)*(s-c))
    where p = a+b+c
          s = p `div` 2

-- (esTriangulo a b c) se verifica si los números a, b y c (con a <= b <= c)
-- pueden ser los lados de un triángulo (es decir, cada uno es menor que
-- la suma de los otros dos). Por ejemplo,
--    esTriangulo 3 4 5  ==  True
--    esTriangulo 1 1 2  ==  False
esTriangulo :: Int -> Int -> Int -> Bool
esTriangulo a b c = c < a+b

-- (esCuadrado n) se verifica si n es un cuadrado perfecto. Por ejemplo,
--    esCuadrado 25  ==  True
--    esCuadrado 26  ==  False
esCuadrado :: Int -> Bool
esCuadrado n = x*x == n
    where x = round (sqrt (fromIntegral n))

-- (mcd a b c) es el máximo común divisor de a, b y c. Por ejemplo,
--    mcd 3 4 5   ==  1
--    mcd 6 8 10  ==  2
mcd :: Int -> Int -> Int -> Int
mcd a b c = gcd a (gcd b c)