Advertisement
banovski

Ninety-Nine Haskell Problems: #9

Mar 31st, 2025 (edited)
1,570
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 2.09 KB | Source Code | 0 0
  1. -- Pack consecutive duplicates of list elements into sublists. If a
  2. -- list contains repeated elements they should be placed in separate
  3. -- sublists.
  4.  
  5. import Data.List (group)
  6. -- "group" is imported as a reference function
  7.  
  8. main :: IO ()
  9. main = do
  10.   putStrLn "Test strings: "
  11.   mapM_ print $ chunksOfFour testStringList
  12.   putStrLn "\nTested functions validity check: "
  13.   mapM_ (print . testFunction) testFuncList
  14.  
  15. testStringList :: [String]
  16. testStringList = pure (\a b c d -> [a, b, c, d])
  17.   <*> "ab"
  18.   <*> "ab"
  19.   <*> "ab"
  20.   <*> "ab"
  21.  
  22. chunksOfFour :: [a] -> [[a]]
  23. chunksOfFour [] = []
  24. chunksOfFour lst = take 4 lst : chunksOfFour (drop 4 lst)
  25.  
  26. testFuncList :: Eq a => [[a] -> [[a]]]
  27. testFuncList = [zero, one, two, three]
  28.  
  29. testFunction :: (String -> [String]) -> Bool
  30. testFunction function =
  31.   -- group from Data.List is used to produce reference results
  32.   map function testStringList == map group testStringList
  33.  
  34. -- Functions were tested on a list with duplicates, 1000405 items
  35. -- long. Time each function takes to complete the task is measured in
  36. -- ticks.
  37.  
  38. -- 128 ticks
  39. zero :: Eq a => [a] -> [[a]]
  40. zero = group
  41.  
  42. -- 221 ticks
  43. one :: Eq a => [a] -> [[a]]
  44. one [] = []
  45. one [a] = [[a]]
  46. one lst = go [head lst] (tail lst)
  47.   where
  48.     go a [] = [a]
  49.     go a (x:xs)
  50.         | head a == x = go (a ++ [x]) xs
  51.         | otherwise = a : go [x] xs
  52.  
  53. -- 285 ticks
  54. two :: Eq a => [a] -> [[a]]
  55. two lst =
  56.   let
  57.     itemsAsLists = map (:[]) lst
  58.     h = head itemsAsLists
  59.     t = tail itemsAsLists
  60.     join a [] = [a]
  61.     join acc (x:xs)
  62.       | head acc == head x = join (acc ++ x) xs
  63.       | otherwise = acc : join x xs
  64.   in
  65.     join h t
  66.  
  67. -- 138 ticks
  68. three :: Eq a => [a] -> [[a]]
  69. three [] = []
  70. three [x] = [[x]]
  71. three lst = foldr go [[last lst]] (init lst)
  72.   where
  73.     go x (y:ys)
  74.       | x == head y = (x : y) : ys
  75.       | otherwise = [x] : y : ys
  76.  
  77. -- Test strings:
  78. -- ["aaaa","aaab","aaba","aabb"]
  79. -- ["abaa","abab","abba","abbb"]
  80. -- ["baaa","baab","baba","babb"]
  81. -- ["bbaa","bbab","bbba","bbbb"]
  82.  
  83. -- Tested functions validity check:
  84. -- True
  85. -- True
  86. -- True
  87. -- True
  88.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement