Skip to content

Commit

Permalink
Add run-length-encoding example
Browse files Browse the repository at this point in the history
  • Loading branch information
tgecho committed Mar 12, 2016
1 parent 862d6e7 commit db1226b
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
3 changes: 2 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"rna-transcription",
"hamming",
"word-count",
"bob"
"bob",
"run-length-encoding"
],
"deprecated": [

Expand Down
3 changes: 2 additions & 1 deletion elm-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"./exercises/rna-transcription",
"./exercises/hamming",
"./exercises/word-count",
"./exercises/bob"
"./exercises/bob",
"./exercises/run-length-encoding"
],
"exposed-modules": [],
"dependencies": {
Expand Down
1 change: 1 addition & 0 deletions exercises/run-length-encoding/RunLengthEncoding.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module RunLengthEncoding (..) where
63 changes: 63 additions & 0 deletions exercises/run-length-encoding/RunLengthEncoding.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module RunLengthEncoding (..) 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 follow.


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 )
40 changes: 40 additions & 0 deletions exercises/run-length-encoding/RunLengthEncodingTests.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module Main (..) where

import Task
import Console
import ElmTest exposing (..)
import RunLengthEncoding exposing (decode, encode)


tests : Test
tests =
suite
"RunLengthEncoding"
[ test "encode simple" (assertEqual "2A3B4C" (encode "AABBBCCCC"))
, test "decode simple" (assertEqual "AABBBCCCC" (decode "2A3B4C"))
, test
"encode with single values"
(assertEqual
"12WB12W3B24WB"
(encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")
)
, test
"decode with single values"
(assertEqual
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"
(decode "12WB12W3B24WB")
)
, test
"decode(encode(...)) combination"
(assertEqual
"zzz ZZ zZ"
(decode (encode "zzz ZZ zZ"))
)
, test "encode unicode" (assertEqual "⏰3⚽2⭐⏰" (encode "⏰⚽⚽⚽⭐⭐⏰"))
, test "decode unicode" (assertEqual "⏰⚽⚽⚽⭐⭐⏰" (decode "⏰3⚽2⭐⏰"))
]


port runner : Signal (Task.Task x ())
port runner =
Console.run (consoleRunner tests)

0 comments on commit db1226b

Please sign in to comment.