Run-length encoding: Difference between revisions

Content added Content deleted
(Emacs Lisp: Count first, then character)
(→‎Haskell: Added a variant expressed as a fold.)
Line 2,908: Line 2,908:
<pre>W12B1W12B3W24B1W14
<pre>W12B1W12B3W24B1W14
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
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>
True</pre>