-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBandera_tricolor.hs
140 lines (114 loc) · 3.99 KB
/
Bandera_tricolor.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
-- Bandera_tricolor.hs
-- La bandera tricolor.
-- José A. Alonso Jiménez <https://jaalonso.github.io>
-- Sevilla, 1-febrero-2025
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- El problema de la bandera tricolor consiste en lo siguiente: Dada un
-- lista de objetos xs que pueden ser rojos, amarillos o morados, se pide
-- devolver una lista ys que contiene los elementos de xs, primero los
-- rojos, luego los amarillos y por último los morados.
--
-- Definir el tipo de dato Color para representar los colores con los
-- constructores R, A y M correspondientes al rojo, azul y morado y la
-- función
-- banderaTricolor :: [Color] -> [Color]
-- tal que (banderaTricolor xs) es la bandera tricolor formada con los
-- elementos de xs. Por ejemplo,
-- banderaTricolor [M,R,A,A,R,R,A,M,M] == [R,R,R,A,A,A,M,M,M]
-- banderaTricolor [M,R,A,R,R,A] == [R,R,R,A,A,M]
-- ---------------------------------------------------------------------
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module Bandera_tricolor where
import Data.List (sort)
import Test.Hspec (Spec, describe, hspec, it, shouldBe)
import Test.QuickCheck
data Color = R | A | M
deriving (Show, Eq, Ord, Enum)
-- 1ª solución
-- ===========
banderaTricolor1 :: [Color] -> [Color]
banderaTricolor1 xs =
[x | x <- xs, x == R] ++
[x | x <- xs, x == A] ++
[x | x <- xs, x == M]
-- 2ª solución
-- ===========
banderaTricolor2 :: [Color] -> [Color]
banderaTricolor2 xs =
colores R ++ colores A ++ colores M
where colores c = filter (== c) xs
-- 3ª solución
-- ===========
banderaTricolor3 :: [Color] -> [Color]
banderaTricolor3 xs =
concat [[x | x <- xs, x == c] | c <- [R,A,M]]
-- 4ª solución
-- ===========
banderaTricolor4 :: [Color] -> [Color]
banderaTricolor4 xs = aux xs ([],[],[])
where aux [] (rs,as,ms) = rs ++ as ++ ms
aux (R:ys) (rs,as,ms) = aux ys (R:rs, as, ms)
aux (A:ys) (rs,as,ms) = aux ys ( rs, A:as, ms)
aux (M:ys) (rs,as,ms) = aux ys ( rs, as, M:ms)
-- 5ª solución
-- ===========
banderaTricolor5 :: [Color] -> [Color]
banderaTricolor5 = sort
-- Verificación
-- ============
verifica :: IO ()
verifica = hspec spec
specG :: ([Color] -> [Color]) -> Spec
specG banderaTricolor = do
it "e1" $
banderaTricolor [M,R,A,A,R,R,A,M,M] `shouldBe` [R,R,R,A,A,A,M,M,M]
it "e2" $
banderaTricolor [M,R,A,R,R,A] `shouldBe` [R,R,R,A,A,M]
spec :: Spec
spec = do
describe "def. 1" $ specG banderaTricolor1
describe "def. 2" $ specG banderaTricolor2
describe "def. 3" $ specG banderaTricolor3
describe "def. 4" $ specG banderaTricolor4
describe "def. 5" $ specG banderaTricolor5
-- La verificación es
-- λ> verifica
-- 10 examples, 0 failures
-- Comprobación de equivalencia
-- ============================
instance Arbitrary Color where
arbitrary = elements [A,R,M]
-- La propiedad es
prop_banderaTricolor :: [Color] -> Bool
prop_banderaTricolor xs =
all (== banderaTricolor1 xs)
[banderaTricolor2 xs,
banderaTricolor3 xs,
banderaTricolor4 xs,
banderaTricolor5 xs]
-- La comprobación es
-- λ> quickCheck prop_banderaTricolor
-- +++ OK, passed 100 tests.
-- Comparación de eficiencia
-- =========================
-- La comparación es
-- λ> bandera n = concat [replicate n c | c <- [M,R,A]]
-- λ> length (banderaTricolor1 (bandera (10^6)))
-- 3000000
-- (1.51 secs, 1,024,454,768 bytes)
-- λ> length (banderaTricolor1 (bandera (2*10^6)))
-- 6000000
-- (2.94 secs, 2,048,454,832 bytes)
-- λ> length (banderaTricolor2 (bandera (2*10^6)))
-- 6000000
-- (2.35 secs, 1,232,454,920 bytes)
-- λ> length (banderaTricolor3 (bandera (2*10^6)))
-- 6000000
-- (4.28 secs, 2,304,455,360 bytes)
-- λ> length (banderaTricolor4 (bandera (2*10^6)))
-- 6000000
-- (3.01 secs, 1,904,454,672 bytes)
-- λ> length (banderaTricolor5 (bandera (2*10^6)))
-- 6000000
-- (2.47 secs, 1,248,454,744 bytes)