Emparejamiento binario
Definir la función
1 |
zipBinario :: [a -> b -> c] -> [a] -> [b] -> [c] |
tal que (zipBinario fs xs ys) es la lista obtenida aplicando cada una de las operaciones binarias de fs a los correspondientes elementos de xs e ys. Por ejemplo,
1 2 3 |
zipBinario [(+), (*), (*)] [2,2,2] [4,4,4] == [6,8,8] zipBinario [(+)] [2,2,2] [4,4,4] == [6] zipBinario [(<), (==), (==)] "coloca" "lobo" == [True,True,False] |
Soluciones
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 |
import Test.QuickCheck import Test.QuickCheck.HigherOrder import Test.Hspec -- 1ª solución zipBinario1 :: [a -> b -> c] -> [a] -> [b] -> [c] zipBinario1 (f:fs) (x:xs) (y:ys) = f x y : zipBinario1 fs xs ys zipBinario1 _ _ _ = [] -- 2ª solución zipBinario2 :: [a -> b -> c] -> [a] -> [b] -> [c] zipBinario2 fs xs ys = [f x y | (f,(x,y)) <- zip fs (zip xs ys)] -- 3ª solución zipBinario3 :: [a -> b -> c] -> [a] -> [b] -> [c] zipBinario3 fs xs ys = [f x y | (f,x,y) <- zip3 fs xs ys] -- 4ª solución zipBinario4 :: [a -> b -> c] -> [a] -> [b] -> [c] zipBinario4 = zipWith3 id -- Verificación -- ============ especificacion :: ([Int -> Int -> Int] -> [Int] -> [Int] -> [Int]) -> Spec especificacion zipBinario = do it "e1" $ zipBinario [(+), (*), (*)] [2,2,2] [4,4,4] `shouldBe` [6,8,8] it "e2" $ zipBinario [(+)] [2,2,2] [4,4,4] `shouldBe` [6] verifica :: IO () verifica = hspec $ do describe "zipBinario1" $ especificacion zipBinario1 describe "zipBinario2" $ especificacion zipBinario2 describe "zipBinario3" $ especificacion zipBinario3 describe "zipBinario4" $ especificacion zipBinario4 -- La verificación es -- λ> verifica -- -- zipBinario1 -- e1 -- e2 -- zipBinario2 -- e1 -- e2 -- zipBinario3 -- e1 -- e2 -- zipBinario4 -- e1 -- e2 -- -- Finished in 0.0016 seconds -- 8 examples, 0 failures -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_zipBinario :: [Bool -> Bool -> Bool] -> [Bool] -> [Bool] -> Bool prop_zipBinario fs xs ys = all (== zipBinario1 fs xs ys) [g fs xs ys | g <- [zipBinario2, zipBinario3, zipBinario4]] -- La comprobación es -- λ> quickCheck' prop_zipBinario -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> maximum (zipBinario1 (cycle [(+), (*)]) [1..] [1..2*10^6]) -- 4000000000000 -- (2.13 secs, 965,392,072 bytes) -- λ> maximum (zipBinario2 (cycle [(+), (*)]) [1..] [1..2*10^6]) -- 4000000000000 -- (1.86 secs, 1,109,392,176 bytes) -- λ> maximum (zipBinario3 (cycle [(+), (*)]) [1..] [1..2*10^6]) -- 4000000000000 -- (1.93 secs, 981,392,128 bytes) -- λ> maximum (zipBinario4 (cycle [(+), (*)]) [1..] [1..2*10^6]) -- 4000000000000 -- (1.07 secs, 773,392,040 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
Nuevas soluciones
- En los comentarios se pueden escribir nuevas soluciones.
- El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>