99 questions/Solutions/9

From HaskellWiki
< 99 questions‎ | Solutions
Revision as of 16:55, 15 September 2010 by Alatar224 (talk | contribs) (added one more implementation)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

(**) Pack consecutive duplicates of list elements into sublists.

If a list contains repeated elements they should be placed in separate sublists.

pack (x:xs) = let (first,rest) = span (==x) xs
               in (x:first) : pack rest
pack [] = []

A more verbose solution is

pack :: Eq a => [a] -> [[a]]
pack [] = []
pack (x:xs) = (x:first) : pack rest
         where
           getReps [] = ([], [])
           getReps (y:ys)
                   | y == x = let (f,r) = getReps ys in (y:f, r)
                   | otherwise = ([], (y:ys))
           (first,rest) = getReps xs

Similarly, using splitAt and findIndex:

pack :: Eq a => [a] -> [[a]]
pack [] = []
pack (x:xs) = (x:reps) : (pack rest)
    where
        (reps, rest) = maybe ([],xs) (\i -> splitAt i xs) (findIndex (/=x) xs)

This is implemented as group in Data.List.

Another solution using takeWhile and dropWhile:

pack :: (Eq a) => [a] -> [[a]]
pack [] = []
pack (x:xs) = (x : takeWhile (==x) xs) : pack (dropWhile (==x) xs)