{"id":7072,"date":"2022-06-07T06:00:28","date_gmt":"2022-06-07T04:00:28","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=7072"},"modified":"2022-06-03T09:26:49","modified_gmt":"2022-06-03T07:26:49","slug":"primos-circulares","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/primos-circulares\/","title":{"rendered":"Primos circulares"},"content":{"rendered":"<p>Un <strong>primo circular<\/strong> es un n\u00famero tal que todas las rotaciones de  d\u00edgitos producen n\u00fameros primos. Por ejemplo, 195 es un primo circular ya que las rotaciones de sus d\u00edgitos son 197, 971 y 719 y los tres n\u00fameros son primos.<\/p>\n<p>Definir la lista<\/p>\n<pre lang=\"text\">\n   circulares :: [Integer]\n<\/pre>\n<p>cuyo valor es la lista de los n\u00fameros primos circulares. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   take 16 circulares == [2,3,5,7,11,13,17,31,37,71,73,79,97,113,131,197]\n   circulares !! 50   == 933199\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.Numbers.Primes (isPrime, primes)\nimport Test.QuickCheck (Positive (Positive), quickCheck)\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n  \ncirculares1 :: [Integer]\ncirculares1 = filter esCircular1 primes\n\n-- (esCircular1 n) se verifica si n es un n\u00famero circular. Por ejemplo, \n--    esCircular1 197  ==  True\n--    esCircular1 157  ==  False\nesCircular1 :: Integer -> Bool\nesCircular1 = all (isPrime . read) . rotaciones1 . show \n\n-- (rotaciones1 xs) es la lista de las rotaciones obtenidas desplazando\n-- el primer elemento xs al final. Por ejemplo,\n--    rotaciones1 [2,3,5]  ==  [[2,3,5],[3,5,2],[5,2,3]]\nrotaciones1 :: [a] -> [[a]]\nrotaciones1 xs = reverse (aux (length xs) [xs])\n    where aux 1 yss      = yss\n          aux n (ys:yss) = aux (n-1) (rota ys : ys :yss)\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n  \ncirculares2 :: [Integer]\ncirculares2 = filter esCircular2 primes\n\nesCircular2 :: Integer -> Bool\nesCircular2 = all (isPrime . read) . rotaciones2 . show \n\nrotaciones2 :: [a] -> [[a]]\nrotaciones2 xs = take (length xs) (iterate rota xs)\n\n-- (rota xs) es la lista a\u00f1adiendo el primer elemento de xs al\n-- final. Por ejemplo, \n--    rota [3,2,5,7]  ==  [2,5,7,3]\nrota :: [a] -> [a]\nrota (x:xs) = xs ++ [x]\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\ncirculares3 :: [Integer]\ncirculares3 = filter (all isPrime . rotaciones3) primes \n\nrotaciones3 :: Integer -> [Integer]\nrotaciones3 n = [read (take m (drop i (cycle s))) | i <- [1..m]]\n    where s = show n\n          m = length s\n\n-- 4\u00aa definici\u00f3n\n-- =============\n\n-- Nota. La 4\u00aa definici\u00f3n es una mejora observando que para que n sea un\n-- n\u00famero primo circular es necesario que todos los d\u00edgitos de n sean\n-- impares, salvo para n = 2. \n\ncirculares4 :: [Integer]\ncirculares4 = 2 : filter esCircular4 primes\n\n-- (esCircular4 n) se verifica si n es un n\u00famero circular. Por ejemplo, \n--    esCircular4 197  ==  True\n--    esCircular4 157  ==  False\nesCircular4 :: Integer -> Bool\nesCircular4 n = digitosImpares n && \n                all (isPrime . read) (rotaciones2 (show n))\n\n-- (digitosImpares n) se verifica si todos los d\u00edgitos de n son\n-- impares. Por ejemplo,\n--    digitosImpares 7351  ==  True\n--    digitosImpares 7341  ==  False\ndigitosImpares :: Integer -> Bool\ndigitosImpares = all (`elem` \"135679\") . show\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_circulares :: Positive Int -> Bool\nprop_circulares (Positive n) =\n  all (== circulares1 !! n)\n      [circulares2 !! n,\n       circulares3 !! n,\n       circulares4 !! n]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheckWith (stdArgs {maxSize=50}) prop_circulares\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> circulares1 !! 46\n--    331999\n--    (2.08 secs, 7,229,208,200 bytes)\n--    \u03bb> circulares2 !! 46\n--    331999\n--    (1.93 secs, 7,165,043,992 bytes)\n--    \u03bb> circulares3 !! 46\n--    331999\n--    (0.74 secs, 2,469,098,648 bytes)\n--    \u03bb> circulares4 !! 46\n--    331999\n--    (0.28 secs, 917,501,600 bytes)\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Primos_circulares.hs\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un primo circular es un n\u00famero tal que todas las rotaciones de d\u00edgitos producen n\u00fameros primos. Por ejemplo, 195 es un primo circular ya que las rotaciones de sus d\u00edgitos son 197, 971 y 719 y los tres n\u00fameros son primos. Definir la lista circulares :: [Integer] cuyo valor es la lista de los n\u00fameros&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[2],"tags":[521],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7072"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=7072"}],"version-history":[{"count":3,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7072\/revisions"}],"predecessor-version":[{"id":7075,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7072\/revisions\/7075"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=7072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=7072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=7072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}