{"id":8481,"date":"2024-02-04T06:00:34","date_gmt":"2024-02-04T04:00:34","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=8481"},"modified":"2024-02-23T10:44:02","modified_gmt":"2024-02-23T08:44:02","slug":"04-feb-24","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/04-feb-24\/","title":{"rendered":"Primos cubanos"},"content":{"rendered":"<p>Un <a href=\"http:\/\/bit.ly\/1jPy5QZ\">primo cubano<\/a> es un n\u00famero primo que se puede escribir como diferencia de dos cubos consecutivos. Por ejemplo, el 61 es un primo cubano porque es primo y 61 = 5\u00b3-4\u00b3.<\/p>\n<p>Definir la sucesi\u00f3n<\/p>\n<pre lang=\"text\">\n   cubanos :: [Integer]\n<\/pre>\n<p>tal que sus elementos son los n\u00fameros cubanos. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> take 15 cubanos\n   [7,19,37,61,127,271,331,397,547,631,919,1657,1801,1951,2269]\n<\/pre>\n<p><!--more--><\/p>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nmodule Primos_cubanos where\n\nimport Data.Numbers.Primes (isPrime)\nimport Test.QuickCheck\nimport Test.Hspec (Spec, describe, hspec, it, shouldBe)\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\ncubanos1 :: [Integer]\ncubanos1 = filter isPrime (zipWith (-) (tail cubos) cubos)\n\n-- cubos es la lista de los cubos. Por ejemplo,\n--    \u03bb> take 10 cubos\n--    [1,8,27,64,125,216,343,512,729,1000]\ncubos :: [Integer]\ncubos = map (^3) [1..]\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\ncubanos2 :: [Integer]\ncubanos2 = filter isPrime [(x+1)^3 - x^3 | x <- [1..]]\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\ncubanos3 :: [Integer]\ncubanos3 = filter isPrime [3*x^2 + 3*x + 1 | x <- [1..]]\n\n-- Verificaci\u00f3n\n-- ============\n\nverifica :: IO ()\nverifica = hspec spec\n\nspecG :: [Integer] -> Spec\nspecG cubanos = do\n  it \"e1\" $\n    take 15 cubanos `shouldBe`\n    [7,19,37,61,127,271,331,397,547,631,919,1657,1801,1951,2269]\n\nspec :: Spec\nspec = do\n  describe \"def. 1\" $ specG cubanos1\n  describe \"def. 2\" $ specG cubanos2\n  describe \"def. 3\" $ specG cubanos3\n\n-- La verificaci\u00f3n es\n--    \u03bb> verifica\n--\n--    3 examples, 0 failures\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_cubanos :: NonNegative Int -> Bool\nprop_cubanos (NonNegative n) =\n  all (== cubanos1 !! n)\n      [cubanos2 !! n,\n       cubanos3 !! n]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_cubanos\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> cubanos1 !! 3000\n--    795066361\n--    (4.21 secs, 16,953,612,192 bytes)\n--    \u03bb> cubanos2 !! 3000\n--    795066361\n--    (4.27 secs, 16,962,597,288 bytes)\n--    \u03bb> cubanos3 !! 3000\n--    795066361\n--    (4.29 secs, 16,956,085,672 bytes)\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom itertools import count, islice, tee\nfrom timeit import Timer, default_timer\nfrom typing import Iterator\n\nfrom sympy import isprime\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\n# cubos() es la lista de los cubos. Por ejemplo,\n#    >>> list(islice(cubos(), 10))\n#    [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]\ndef cubos() -> Iterator[int]:\n    return (x**3 for x in count(1))\n\n# parejasDeCubos() es la lista de las parejas de cubos consecutivos. Por\n# ejemplo,\n#    >>> list(islice(parejasDeCubos(), 5))\n#    [(1, 8), (8, 27), (27, 64), (64, 125), (125, 216)]\ndef parejasDeCubos() -> Iterator[tuple[int, int]]:\n    a, b = tee(cubos())\n    next(b, None)\n    return zip(a, b)\n\n# diferenciasDeCubos() es la lista de las diferencias de cubos\n# consecutivos. Por ejemplo,\n#    >>> list(islice(diferenciasDeCubos(), 5))\n#    [7, 19, 37, 61, 91]\ndef diferenciasDeCubos() -> Iterator[int]:\n    return (j - i for i, j in parejasDeCubos())\n\ndef cubanos1() -> Iterator[int]:\n    return (x for x in diferenciasDeCubos() if isprime(x))\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef cubanos2() -> Iterator[int]:\n    return ((x+1)**3 - x**3 for x in count(1) if isprime((x+1)**3 - x**3))\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef cubanos3() -> Iterator[int]:\n    return (y for x in count(1) if isprime((y := (x+1)**3 - x**3)))\n\n# 4\u00aa soluci\u00f3n\n# ===========\n\ndef cubanos4() -> Iterator[int]:\n    return (y for x in count(1) if isprime((y := 3*x**2 + 3*x + 1)))\n\n# Verificaci\u00f3n\n# ============\n\ndef test_cubanos() -> None:\n    for cubanos in [cubanos1, cubanos2, cubanos3, cubanos4]:\n        assert list(islice(cubanos(), 15)) == \\\n            [7,19,37,61,127,271,331,397,547,631,919,1657,1801,1951,2269]\n    print (\"Verificado\")\n\n# La verificaci\u00f3n es\n#    >>> test_cubanos()\n#    Verificado\n\n# Comprobaci\u00f3n de equivalencia\n# ============================\n\n# La propiedad es\ndef test_cubanos_equiv(n: int) -> None:\n    r = list(islice(cubanos1(), n))\n    assert list(islice(cubanos2(), n)) == r\n    assert list(islice(cubanos3(), n)) == r\n    assert list(islice(cubanos4(), n)) == r\n    print(\"Verificado\")\n\n# La comprobaci\u00f3n es\n#    >>> test_cubanos_equiv(10000)\n#    Verificado\n\n# Comparaci\u00f3n de eficiencia\n# =========================\n\ndef tiempo(e: str) -> None:\n    \"\"\"Tiempo (en segundos) de evaluar la expresi\u00f3n e.\"\"\"\n    t = Timer(e, \"\", default_timer, globals()).timeit(1)\n    print(f\"{t:0.2f} segundos\")\n\n# La comparaci\u00f3n es\n#    >>> tiempo('list(islice(cubanos1(), 30000))')\n#    1.54 segundos\n#    >>> tiempo('list(islice(cubanos1(), 40000))')\n#    2.20 segundos\n#    >>> tiempo('list(islice(cubanos2(), 40000))')\n#    2.22 segundos\n#    >>> tiempo('list(islice(cubanos3(), 40000))')\n#    2.19 segundos\n#    >>> tiempo('list(islice(cubanos4(), 40000))')\n#    2.15 segundos\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Un primo cubano es un n\u00famero primo que se puede escribir como diferencia de dos cubos consecutivos. Por ejemplo, el 61 es un primo cubano porque es primo y 61 = 5\u00b3-4\u00b3. Definir la sucesi\u00f3n cubanos :: [Integer] tal que sus elementos son los n\u00fameros cubanos. Por ejemplo, \u03bb> take 15 cubanos [7,19,37,61,127,271,331,397,547,631,919,1657,1801,1951,2269]<\/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":"default","_kad_post_title":"default","_kad_post_layout":"default","_kad_post_sidebar_id":"","_kad_post_content_style":"default","_kad_post_vertical_padding":"default","_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":[581],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8481"}],"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=8481"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8481\/revisions"}],"predecessor-version":[{"id":8499,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8481\/revisions\/8499"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=8481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=8481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=8481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}