Definir la función
desemparejada :: [(a,b)] -> ([a],[b]) |
tal que (desemparejada ps) es el par de lista (xs,ys) tal que al emparejar (con zip) xs e ys devuelve ps. Por ejemplo,
ghci> desemparejada [(3,'l'),(2,'u'),(5,'i'),(9,'s')] ([3,2,5,9],"luis") |
Comprobar con QuickCheck que
- desemparejada es equivalente a la función predefinida unzip.
- si el valor de (desemparejada ps) es (xs,ys), entonces (zip xs ys) es igual a ps.
Soluciones
import Test.QuickCheck -- 1ª definición (por comprensión): desemparejada1 :: [(a,b)] -> ([a],[b]) desemparejada1 ps = ([x | (x,_) <- ps], [y | (_,y) <- ps]) -- 2ª definición (con map): desemparejada2 :: [(a,b)] -> ([a],[b]) desemparejada2 ps = (map fst ps, map snd ps) -- 3ª definición (por recursión): desemparejada3 :: [(a,b)] -> ([a],[b]) desemparejada3 [] = ([],[]) desemparejada3 ((x,y):ps) = (x:xs,y:ys) where (xs,ys) = desemparejada3 ps -- 4ª definición (por plegado): desemparejada4 :: [(a,b)] -> ([a],[b]) desemparejada4 = foldr f ([],[]) where f (x,y) (xs,ys) = (x:xs, y:ys) -- 5ª definición (por plegado por la izquierda): desemparejada5 :: [(a,b)] -> ([a],[b]) desemparejada5 ps = (reverse us, reverse vs) where (us,vs) = foldl f ([],[]) ps f (xs,ys) (x,y) = (x:xs,y:ys) -- Comparación de eficiencia- -- ghci> let ps = zip [1..10^7] [1..10^7] -- -- ghci> length (fst (desemparejada1 ps)) -- 10000000 -- (3.67 secs, 360441524 bytes) -- -- ghci> length (fst (desemparejada2 ps)) -- 10000000 -- (0.38 secs, 440476764 bytes) -- -- ghci> length (fst (desemparejada3 ps)) -- 10000000 -- (14.11 secs, 2160188668 bytes) -- -- ghci> length (fst (desemparejada4 ps)) -- 10000000 -- (19.08 secs, 1658689692 bytes) -- -- ghci> length (fst (desemparejada5 ps)) -- 10000000 -- (20.98 secs, 1610061796 bytes) -- En lo que sigue, usaremos la 2º definición desemparejada :: [(a,b)] -> ([a],[b]) desemparejada = desemparejada2 -- La primera propiedad es prop_desemparejada_1 :: (Eq a, Eq b) => [(a,b)] -> Bool prop_desemparejada_1 ps = desemparejada ps == unzip ps -- Su comprobación es -- ghci> quickCheck prop_desemparejada_1 -- +++ OK, passed 100 tests. -- La segunda propiedad es prop_desemparejada_2 :: (Eq a, Eq b) => [(a,b)] -> Bool prop_desemparejada_2 ps = zip xs ys == ps where (xs,ys) = desemparejada ps -- Su comprobación es -- ghci> quickCheck prop_desemparejada_2 -- +++ OK, passed 100 tests. |
2 Comments