Compactación de listas
Definir la función
1 |
compactada :: [Maybe Int] -> [Int] |
tal que (compacta xs) es la lista obtenida al compactar xs con las siguientes reglas:
- se eliminan los elementos Nothing;
- si dos elementos consecutivos tienen el mismo valor, se sustituyen por el sucesor de su valor y
- los restantes elementos no se cambian.
Por ejemplo,
1 2 3 4 5 6 7 8 9 10 |
λ> compactada [Just 1,Nothing,Just 1,Just 4,Just 4,Just 3,Just 6] [2,5,3,6] λ> compactada [Just 1,Nothing,Just 1,Just 1,Just 4,Just 3,Just 6] [2,1,4,3,6] λ> compactada [Just 1,Nothing,Just 1,Just 1,Just 4,Just 4,Just 6] [2,1,5,6] λ> compactada [Just 1,Nothing,Just 1,Just 1,Just 4,Just 3,Just 4] [2,1,4,3,4] λ> compactada [Just 1,Nothing,Just 1,Just 2,Just 4,Just 3,Just 4] [2,2,4,3,4] |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
-- 1ª definición compactada1 :: [Maybe Int] -> [Int] compactada1 xs = aux (valores xs) where aux (x:y:xs) | x == y = x+1 : aux xs | otherwise = x : aux (y:xs) aux xs = xs -- (valores vs) es la lista de los valores de vs. Por ejemplo, -- ghci> valores [Just 1,Nothing,Just 1,Nothing,Just 3,Just 6] -- [1,1,3,6] valores :: [Maybe Int] -> [Int] valores xs = [x | Just x <- xs] -- 2ª definición de valores (por recursión): valores2 :: [Maybe Int] -> [Int] valores2 [] = [] valores2 ((Just v):vs) = v: valores2 vs valores2 (Nothing:vs) = valores2 vs |
Si aplicas
aux
a la lista completa, se colapsa en casos como el siguiente, lo que no parece la intención de la función:Los únicos números iguales son 1 y 1. Podría interpretarse que el resultado deseado es
[2,2,3,4]
. Sin embargo, tu función colapsa todos los valores y devuelve[5]
. Habría sido de ayuda un ejemplo similar a este para que se observe dónde deberíamos aplicar la función.Mi interpreción es que las reglas son aplicables mientras sea posible. Tienes razón que sólo se tiene que hacer la primera sustitución, tal y como muestra el último ejemplo:
Por tanto mi solución no es correcta.