Run-length encoding: Difference between revisions

→‎Haskell: Added a variant expressed as a fold.
(Emacs Lisp: Count first, then character)
(→‎Haskell: Added a variant expressed as a fold.)
Line 2,908:
<pre>W12B1W12B3W24B1W14
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
True</pre>
 
===As a fold===
<lang haskell>import Data.Bifunctor (first)
 
----------------------- RUN LENGTHS ----------------------
 
runLengths :: String -> [(Int, Char)]
runLengths "" = []
runLengths s =
let go c ("", xs) = ([c], xs)
go c (cs@(x : run), xs)
| c == x = (c : cs, xs)
| otherwise = ([c], (length cs, x) : xs)
in uncurry
(:)
( first
((,) . length <*> head)
(foldr go ("", []) s)
)
 
--------------------------- TEST -------------------------
main :: IO ()
main = do
let testString =
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWW"
<> "WWWWWWWWWWBWWWWWWWWWWWWWW"
encoded = runLengths testString
putStrLn $ showLengths encoded
print $ concatMap (uncurry replicate) encoded == testString
 
------------------------- DISPLAY ------------------------
showLengths :: [(Int, Char)] -> String
showLengths [] = []
showLengths ((n, c) : xs) = show n <> [c] <> showLengths xs</lang>
{{Out}}
<pre>12W1B12W3B24W1B14W
True</pre>
 
9,655

edits