elm/exercises/run-length-encoding/RunLengthEncoding.example

66 lines
1.5 KiB
Text
Raw Normal View History

module RunLengthEncoding (encode, decode) where
import String exposing (fromChar)
import List exposing (head, tail)
import Maybe exposing (withDefault)
import Regex
{-
To the unaware: this was written by a very green elmer, so don't consider
it an idiomatic exemplar to emulate.
-}
encode : String -> String
encode string =
String.toList string
|> List.foldr countChars []
|> List.map stringifyCounts
|> String.join ""
countChars : a -> List ( number, a ) -> List ( number, a )
countChars current counted =
case head counted of
Just ( count, previous ) ->
if previous == current then
( count + 1, current ) :: withDefault [] (tail counted)
else
( 1, current ) :: counted
Nothing ->
[ ( 1, current ) ]
stringifyCounts : ( number, Char ) -> String
stringifyCounts ( count, char ) =
if count > 1 then
toString count ++ fromChar char
else
fromChar char
decode : String -> String
decode string =
string
|> Regex.find Regex.All (Regex.regex "(\\d+)|(\\D)")
|> List.map .match
|> List.foldl expandCounts ( "", Nothing )
|> fst
expandCounts : String -> ( String, Maybe Int ) -> ( String, Maybe Int )
expandCounts match ( result, count ) =
case count of
Just number ->
( result ++ String.repeat number match, Nothing )
Nothing ->
case String.toInt match of
Ok number ->
( result, Just number )
Err _ ->
( result ++ match, Nothing )