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.
Nota: Este ejercicio está basado en la noticia Descubierta una nueva propiedad de los números primos gracias a The Big Bang Theory donde podéis leer más información sobre el tema, entre ello la prueba de que el 73 es el único número 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.