Número primo de Sheldon
En el episodio número 73 de la serie The Big Bang Theory, Sheldon Cooper enuncia lo siguiente:
«El mejor número es el 73. El 73 es el 21-ésimo número primo. Al invertir sus cifras obtenemos 37, que es el primo número 12. Y al invertir este obtenemos 21, que es el producto de ─agarraos fuerte─ 7 y 3.»
Se define un número primo de Sheldon como: el n-ésimo número primo p(n) será un primo de Sheldon si cumple que el producto de sus dígitos es n y si, además, el número que se obtiene al invertir sus cifras, rev(p(n)), es el rev(n)-ésimo número primo; es decir, si rev(p(n)) = p(rev(n)).
Definir la función
esPrimoSheldon :: Int -> Bool
tal que (esPrimoSheldon x) se verifica si x un primo de Sheldon. Por ejemplo,
esPrimoSheldon 73 == True esPrimoSheldon 79 == False
Comprobar con QuickCheck que 73 es el único primo de Sheldon.
Soluciones
import Data.Char (digitToInt) import Data.List (elemIndex) import Data.Maybe (fromJust) import Data.Numbers.Primes (isPrime, primes) import Test.QuickCheck (Property, (==>), quickCheck) -- 1ª definición -- ============= esPrimoSheldon :: Int -> Bool esPrimoSheldon x = n > 0 && x == primes !! (n - 1) && inverso x == primes !! (inverso n - 1) where n = productoDigitos x -- (productoDigitos x) es el producto de los dígitos de x. Por ejemplo, -- productoDigitos 73 == 21 productoDigitos :: Int -> Int productoDigitos x = product (map digitToInt (show x)) -- (inverso x) es el número obtenido invirtiendo el orden de los dígitos -- de x. Por ejemplo, -- inverso 735 == 537 inverso :: Int -> Int inverso x = read (reverse (show x)) -- 2ª definición -- ============= esPrimoSheldon2 :: Int -> Bool esPrimoSheldon2 x = n > 0 && x == primes !! (n - 1) && inverso2 x == primes !! (inverso2 n - 1) where n = productoDigitos2 x -- (productoDigitos2 x) es el producto de los dígitos de x. Por ejemplo, -- productoDigitos2 73 == 21 productoDigitos2 :: Int -> Int productoDigitos2 = product . map digitToInt . show -- (inverso2 x) es el número obtenido invirtiendo el orden de los dígitos -- de x. Por ejemplo, -- inverso2 735 == 537 inverso2 :: Int -> Int inverso2 = read . reverse . show -- 3ª definición -- ============= esPrimoSheldon3 :: Int -> Bool esPrimoSheldon3 n = isPrime n && p1 && p2 where p = primes i1 = fromJust (elemIndex n p) + 1 i2 = read (reverse (show i1)) p1 = i1 == product (map digitToInt (show n)) p2 = read (reverse (show n)) == p !! (i2 - 1) -- Propiedad de primo de Sheldon -- ============================= -- La propiedad es prop_primoDeShelldon :: Int -> Property prop_primoDeShelldon x = x >= 0 ==> esPrimoSheldon x == (x == 73) -- La comprobación es -- λ> quickCheck prop_primoDeShelldon -- +++ OK, passed 100 tests.