-- | -- Module : Segmentos_consecutivos.hs -- Description : Segmentos de elementos consecutivos. -- Copyright : Exercitium (07-05-14) -- License : GPL-3 -- Maintainer : JoseA.Alonso@gmail.com -- -- Definir la función -- -- > segmentos :: (Enum a, Eq a) => [a] -> [[a]] -- -- tal que __(segmentos xss)__ es la lista de los segmentos de xss formados -- por elementos consecutivos. Por ejemplo, -- -- >>> segmentos [1,2,5,6,4] -- [[1,2],[5,6],[4]] -- >>> segmentos [1,2,3,4,7,8,9] -- [[1,2,3,4],[7,8,9]] -- >>> segmentos "abbccddeeebc" -- ["ab","bc","cd","de","e","e","bc"] -- -- Nota: Se puede usar la función succ tal que (succ x) es el sucesor de -- x. Por ejemplo, -- -- > succ 3 == 4 -- > succ 'c' == 'd' module Segmentos_consecutivos where import Test.QuickCheck -- | 1ª definición (por recursión). segmentos :: (Enum a, Eq a) => [a] -> [[a]] segmentos [] = [] segmentos [x] = [[x]] segmentos (x:xs) | y == succ x = (x:y:ys):zs | otherwise = [x]:(y:ys):zs where ((y:ys):zs) = segmentos xs -- | 2ª definición. segmentos2 :: (Enum a, Eq a) => [a] -> [[a]] segmentos2 [] = [] segmentos2 xs = ys : segmentos2 zs where ys = inicial xs n = length ys zs = drop n xs -- | (inicial xs) es el segmento inicial de xs formado por elementos -- consecutivos. Por ejemplo, -- -- >>> inicial [1,2,5,6,4] -- [1,2] -- >>> inicial "abccddeeebc" -- "abc" inicial :: (Enum a, Eq a) => [a] -> [a] inicial [] = [] inicial (x:xs) = [y | (y,_) <- takeWhile (\(u,v) -> u == v) (zip (x:xs) [x..])] -- | 2ª definición de inicial (con uncurry) -- -- >>> inicial2 [1,2,5,6,4] -- [1,2] -- >>> inicial2 "abccddeeebc" -- "abc" inicial2 :: (Enum a, Eq a) => [a] -> [a] inicial2 [] = [] inicial2 (x:xs) = [y | (y,_) <- takeWhile (uncurry (==)) (zip (x:xs) [x..])] -- | (prop_segmentos xs) se verifica si las definiciones de segmentos -- son equivalentes sobre xs. Por ejemplo, -- -- >>> prop_segmentos [1,2,5,6,4] -- True -- >>> prop_segmentos [1,2,3,4,7,8,9] -- True -- >>> prop_segmentos "abbccddeeebc" -- True prop_segmentos :: (Enum a, Eq a) => [a] -> Bool prop_segmentos xs = segmentos xs == segmentos2 xs -- | Comprueba la equivalencia de las definiciones de segmentos. -- -- >>> verifica_segmentos -- +++ OK, passed 100 tests. verifica_segmentos :: IO () verifica_segmentos = quickCheck (prop_segmentos :: [Int] -> Bool)