-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPrimos_cubanos.hs
100 lines (79 loc) · 2.48 KB
/
Primos_cubanos.hs
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
89
90
91
92
93
94
95
96
97
98
99
100
-- Primos_cubanos.hs
-- Primos cubanos.
-- José A. Alonso Jiménez <https://jaalonso.github.io>
-- Sevilla, 4-febrero-2024
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Un [primo cubano](http://bit.ly/1jPy5QZ) es un número 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³-4³.
--
-- Definir la sucesión
-- cubanos :: [Integer]
-- tal que sus elementos son los números cubanos. Por ejemplo,
-- λ> take 15 cubanos
-- [7,19,37,61,127,271,331,397,547,631,919,1657,1801,1951,2269]
-- ---------------------------------------------------------------------
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
module Primos_cubanos where
import Data.Numbers.Primes (isPrime)
import Test.QuickCheck
import Test.Hspec (Spec, describe, hspec, it, shouldBe)
-- 1ª solución
-- ===========
cubanos1 :: [Integer]
cubanos1 = filter isPrime (zipWith (-) (tail cubos) cubos)
-- cubos es la lista de los cubos. Por ejemplo,
-- λ> take 10 cubos
-- [1,8,27,64,125,216,343,512,729,1000]
cubos :: [Integer]
cubos = map (^3) [1..]
-- 2ª solución
-- ===========
cubanos2 :: [Integer]
cubanos2 = filter isPrime [(x+1)^3 - x^3 | x <- [1..]]
-- 3ª solución
-- ===========
cubanos3 :: [Integer]
cubanos3 = filter isPrime [3*x^2 + 3*x + 1 | x <- [1..]]
-- Verificación
-- ============
verifica :: IO ()
verifica = hspec spec
specG :: [Integer] -> Spec
specG cubanos = do
it "e1" $
take 15 cubanos `shouldBe`
[7,19,37,61,127,271,331,397,547,631,919,1657,1801,1951,2269]
spec :: Spec
spec = do
describe "def. 1" $ specG cubanos1
describe "def. 2" $ specG cubanos2
describe "def. 3" $ specG cubanos3
-- La verificación es
-- λ> verifica
--
-- 3 examples, 0 failures
-- Comprobación de equivalencia
-- ============================
-- La propiedad es
prop_cubanos :: NonNegative Int -> Bool
prop_cubanos (NonNegative n) =
all (== cubanos1 !! n)
[cubanos2 !! n,
cubanos3 !! n]
-- La comprobación es
-- λ> quickCheck prop_cubanos
-- +++ OK, passed 100 tests.
-- Comparación de eficiencia
-- =========================
-- La comparación es
-- λ> cubanos1 !! 3000
-- 795066361
-- (4.21 secs, 16,953,612,192 bytes)
-- λ> cubanos2 !! 3000
-- 795066361
-- (4.27 secs, 16,962,597,288 bytes)
-- λ> cubanos3 !! 3000
-- 795066361
-- (4.29 secs, 16,956,085,672 bytes)