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)