Advertisement
Guest User

Untitled

a guest
Jun 10th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module RunLength where
  2.  
  3. import Data.Char
  4. import Data.List
  5.  
  6. rleCompress :: Eq a => [a] -> [(Int, a)]
  7. rleCompress t = zip (map length tt) (map head tt)
  8.   where
  9.     tt = group t
  10.  
  11. lettersAndSpace :: String
  12. lettersAndSpace = ' ' : ['A' .. 'Z'] ++ ['a' .. 'z']
  13.  
  14. allLetters :: String -> Bool
  15. allLetters = all (`elem` lettersAndSpace)
  16.  
  17. intersperseDigits :: String -> String
  18. intersperseDigits encodedText =
  19.   if isAlpha (head encodedText)
  20.     then f ('1' : encodedText)
  21.     else f encodedText
  22.   where
  23.     f = concatMap fu . splitOnDigit
  24.     fu [] = []
  25.     fu [x] = [x]
  26.     fu xs =
  27.       if allLetters xs
  28.         then intersperse '1' xs
  29.         else xs
  30.  
  31. decode :: String -> String
  32. decode [] = []
  33. decode text =
  34.   concatMap (g . f) $
  35.   uncurry zip $ evenOddSplit $ splitOnDigit $ intersperseDigits text
  36.   where
  37.     f (a, b) = (read a :: Integer, head b)
  38.     g (n, y) = map (const y) [1 .. n]
  39.  
  40. encode :: String -> String
  41. encode = concat . filter (/= "1") . splitOnDigit . concatMap f . rleCompress
  42.   where
  43.     f (n, x) = show n ++ [x]
  44.  
  45. groupOn :: Eq b => (a -> b) -> [a] -> [(b, [a])]
  46. groupOn _ [] = []
  47. groupOn proj (x:xs) = (x', x : ys) : groupOn proj zs
  48.  where
  49.    x' = proj x
  50.     (ys, zs) = span ((== x') . proj) xs
  51.  
  52. evenOddSplit :: [a] -> ([a], [a])
  53. evenOddSplit [] = ([], [])
  54. evenOddSplit (x:xs) = (x : o, e)
  55.  where
  56.    (e, o) = evenOddSplit xs
  57.  
  58. splitOnDigit :: String -> [String]
  59. splitOnDigit = map snd . groupOn (`notElem` lettersAndSpace)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement