import Test.QuickCheck
-- 1ª definición
-- =============
pitagoricos :: [Integer]
pitagoricos = [n | n <- [1..], esPitagorico n]
-- (esPitagorico n) se verifica si n es pitagórico. Por ejemplo,
-- esPitagorico 5 == True
-- esPitagorico 6 == False
esPitagorico :: Integer -> Bool
esPitagorico n = not (null (ternasPitagoricas n))
-- (ternasPitagoricas n) es la lista de las ternas (n,a,b) tales que
-- n² = a²+b² con b < a < n. Por ejemplo,
-- ghci> ternasPitagoricas 5
-- [(5,4,3)]
-- ghci> ternasPitagoricas 2015
-- [(2015,1612,1209),(2015,1736,1023),(2015,1860,775),(2015,1953,496)]
ternasPitagoricas :: Integer -> [(Integer,Integer,Integer)]
ternasPitagoricas n =
[(n,a,b) | a <- [1..n-1],
let b2 = n^2-a^2,
let b = round (sqrt (fromIntegral b2)),
b < a,
b^2 == b2]
-- 2ª definición
-- =============
pitagoricos2 :: [Integer]
pitagoricos2 = [round (sqrt (fromIntegral a)) |
a <- cuadrados,
let xs = takeWhile (< a) cuadrados,
any (\b -> a-b `elem` xs) xs]
-- cuadrados es la lista de los cuadrados de los números naturales. Por
-- ejemplo,
-- take 10 cuadrados == [1,4,9,16,25,36,49,64,81,100]
cuadrados :: [Integer]
cuadrados = [n*n | n <- [1..]]
-- El cálculo de la posición de 2015 es
-- ghci> length (takeWhile (< 2015) pitagoricos)
-- 1195