-- | -- Module : Orbita_prima -- Description : Órbita prima. -- Copyright : Exercitium (13-06-14) -- License : GPL-3 -- Maintainer : JoseA.Alonso@gmail.com -- -- __Órbita prima__ -- -- La órbita prima de un número n es la sucesión construida de la -- siguiente forma: -- -- * si n es compuesto su órbita no tiene elementos -- * si n es primo, entonces n está en su órbita; además, sumamos n y -- sus dígitos, si el resultado es un número primo repetimos el -- proceso hasta obtener un número compuesto. -- -- Por ejemplo, con el 11 podemos repetir el proceso dos veces -- -- * 3 = 11+1+1 -- * 17 = 13+1+3 -- -- Así, la órbita prima de 11 es 11, 13, 17. -- -- Definir la función -- -- > orbita :: Integer -> [Integer] -- -- tal que __(orbita n)__ es la órbita prima de n. Por ejemplo, -- -- >>> orbita 11 -- [11,13,17] -- >>> orbita 59 -- [59,73,83] -- -- Calcular el menor número cuya órbita prima tiene más de 3 elementos. module Orbita_prima where import Test.QuickCheck -- | 1ª definición (por recursión) orbita :: Integer -> [Integer] orbita n | not (esPrimo n) = [] | otherwise = n : orbita (n + sum (cifras n)) -- | __(esPrimo n)__ se verifica si n es primo. Por ejemplo, -- -- >>> esPrimo 17 -- True -- >>> esPrimo 21 -- False esPrimo :: Integer -> Bool esPrimo n = [x | x <- [1..n], n `rem` x == 0] == [1,n] -- | __(cifras n)__ es la lista de las cifras de n. Por ejemplo, -- -- >>> cifras 32542 -- [3,2,5,4,2] cifras :: Integer -> [Integer] cifras n = [read [x]| x <- show n] -- | 2ª definición (con iterate) orbita2 :: Integer -> [Integer] orbita2 n = takeWhile esPrimo (iterate f n) where f x = x + sum (cifras x) -- | __(prop_equiv_orbita n)__ se verifica si las definiciones de -- 'orbita' son equivalentes sobre n. Por ejemplo, -- -- >>> all prop_equiv_orbita [11, 59] -- True prop_equiv_orbita :: Integer -> Bool prop_equiv_orbita n = orbita n == orbita2 n -- | Comprueba la equivalencia de las definiciones de 'orbita'. -- -- >>> verifica_equiv_orbita -- +++ OK, passed 100 tests. verifica_equiv_orbita :: IO () verifica_equiv_orbita = quickCheck prop_equiv_orbita -- El cálculo es -- > head [x | x <- [1,3..], length (orbita x) > 3] -- 277 -- -- > orbita 277 -- [277,293,307,317]