Pandigitales primos
Un número con n dígitos es pandigital si contiene todos los dígitos del 1 a n exactamente una vez. Por ejemplo, 2143 es un pandigital con 4 dígitos y, además, es primo.
Definir la lista
1 |
pandigitalesPrimos :: [Int] |
tal que sus elementos son los números pandigitales primos, ordenados de mayor a menor. Por ejemplo,
1 2 3 |
take 3 pandigitalesPrimos == [7652413,7642513,7641253] 2143 `elem` pandigitalesPrimos == True length pandigitalesPrimos == 538 |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
import Data.List (permutations, sort) import Data.Char (intToDigit) import Data.Numbers.Primes (isPrime) -- 1ª solución -- =========== pandigitalesPrimos1 :: [Int] pandigitalesPrimos1 = concatMap nPandigitalesPrimos1 [9,8..1] -- (nPandigitalesPrimos n) es la lista de los números pandigitales con n -- dígitos, ordenada de mayor a menor. Por ejemplo, -- nPandigitalesPrimos 4 == [4231,2341,2143,1423] -- nPandigitalesPrimos 5 == [] nPandigitalesPrimos1 :: Int -> [Int] nPandigitalesPrimos1 n = filter isPrime (pandigitales n) -- (pandigitales n) es la lista de los números pandigitales de n dígitos -- ordenada de mayor a menor. Por ejemplo, -- pandigitales 3 == [321,312,231,213,132,123] pandigitales :: Int -> [Int] pandigitales n = reverse $ sort $ map digitosAentero (permutations [1..n]) -- (digitosAentero ns) es el número cuyos dígitos son ns. Por ejemplo, -- digitosAentero [3,2,5] == 325 digitosAentero :: [Int] -> Int digitosAentero = read . map intToDigit -- 2ª solución -- =========== pandigitalesPrimos2 :: [Int] pandigitalesPrimos2 = concatMap nPandigitalesPrimos2 [9,8..1] -- Nota. La definición de nPandigitalesPrimos1 se puede simplificar, ya -- que la suma de los números de 1 a n es divisible por 3, entonces los -- números pandigitales con n dígitos también lo son y, por tanto, no -- son primos. nPandigitalesPrimos2 :: Int -> [Int] nPandigitalesPrimos2 n | sum [1..n] `mod` 3 == 0 = [] | otherwise = filter isPrime (pandigitales n) -- 2ª solución -- =========== pandigitalesPrimos3 :: [Int] pandigitalesPrimos3 = concatMap nPandigitalesPrimos3 [9,8..1] -- La definición de nPandigitales se puede simplificar, ya que -- λ> [n | n <- [1..9], sum [1..n] `mod` 3 /= 0] -- [1,4,7] nPandigitalesPrimos3 :: Int -> [Int] nPandigitalesPrimos3 n | n `elem` [4,7] = filter isPrime (pandigitales n) | otherwise = [] -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_pandigitalesPrimos :: Bool prop_pandigitalesPrimos = all (== pandigitalesPrimos1) [pandigitalesPrimos2, pandigitalesPrimos3] -- La comprobación es -- λ> prop_pandigitalesPrimos -- True -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> length (pandigitalesPrimos1) -- 538 -- (1.44 secs, 5,249,850,032 bytes) -- λ> length (pandigitalesPrimos2) -- 538 -- (0.14 secs, 619,249,632 bytes) -- λ> length (pandigitalesPrimos3) -- 538 -- (0.14 secs, 619,237,464 bytes) |
El código se encuentra en GitHub.