-
-
Notifications
You must be signed in to change notification settings - Fork 201
dibs: I will implement exercise run-length-encoding #461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| name: run-length-encoding | ||
|
|
||
| dependencies: | ||
| - base | ||
|
|
||
| library: | ||
| exposed-modules: RunLength | ||
| source-dirs: src | ||
|
|
||
| tests: | ||
| test: | ||
| main: Tests.hs | ||
| source-dirs: test | ||
| dependencies: | ||
| - run-length-encoding | ||
| - hspec |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| module RunLength (decode, encode) where | ||
|
|
||
| import Data.Char (isDigit) | ||
|
|
||
| decode :: String -> String | ||
| decode "" = "" | ||
| decode s = replicate n c ++ decode rest | ||
| where | ||
| i = takeWhile isDigit s | ||
| n = if null i then 1 else read i | ||
| c = head $ filter (not . isDigit) s | ||
| rest = drop (1 + length i) s | ||
|
|
||
| encode :: String -> String | ||
| encode "" = "" | ||
| encode s = i ++ c : encode rest | ||
| where | ||
| c = head s | ||
| l = length $ takeWhile (== c) s | ||
| i = if l == 1 then "" else show l | ||
| rest = drop l s |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| name: run-length-encoding | ||
|
|
||
| dependencies: | ||
| - base | ||
|
|
||
| library: | ||
| exposed-modules: RunLength | ||
| source-dirs: src | ||
| dependencies: | ||
| # - foo # List here the packages you | ||
| # - bar # want to use in your solution. | ||
|
|
||
| tests: | ||
| test: | ||
| main: Tests.hs | ||
| source-dirs: test | ||
| dependencies: | ||
| - run-length-encoding | ||
| - hspec |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| module RunLength (decode, encode) where | ||
|
|
||
| import Data.Char (isDigit) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are many ways to solve this problem without using This import would direct people to look for a specific solution, reducing diversity. I think that it should be removed. |
||
|
|
||
| decode :: String -> String | ||
| decode = undefined | ||
|
|
||
| encode :: String -> String | ||
| encode = undefined | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is perfect the way it is and also matches exactly what we did in all the other exercises. Recently, we discussed in #459 that it would be nice to use encode xs = error "You need to implement this function."No change is needed here, and we are not yet in the processes of rewriting the stub solutions. Your choice!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If at a later date the decision is made to replace |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| resolver: lts-7.9 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| {-# LANGUAGE RecordWildCards #-} | ||
|
|
||
| import Data.Foldable (for_) | ||
| import Test.Hspec (Spec, describe, it, shouldBe) | ||
| import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) | ||
|
|
||
| import RunLength (encode, decode) | ||
|
|
||
| main :: IO () | ||
| main = hspecWith defaultConfig {configFastFail = True} specs | ||
|
|
||
| specs :: Spec | ||
| specs = describe "run-length-encoding" $ do | ||
| describe "decode" $ for_ decodeCases $ test decode | ||
| describe "encode" $ for_ encodeCases $ test encode | ||
| describe "both" $ for_ bothCases $ test (decode . encode) | ||
| where | ||
| test f Case{..} = it description $ f input `shouldBe` expected | ||
|
|
||
| -- Test cases adapted from file | ||
| -- `exercism/x-common/exercises/run-length-encoding/canonical-data.json` | ||
| -- on 2016-12-26. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test suite could be better "translated" as a big That said, the cases ordering doesn't seem to be so important in this exercise, so I think it is great the way it is.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made a conscious decision to change the order of the tests. I like having tests for different methods separated so that I can fully implement |
||
|
|
||
| data Case = Case { description :: String | ||
| , input :: String | ||
| , expected :: String | ||
| } | ||
|
|
||
| encodeCases :: [Case] | ||
| encodeCases = | ||
| [ Case { description = "encode empty string" | ||
| , input = "" | ||
| , expected = "" | ||
| } | ||
| , Case { description = "encode single characters only" | ||
| , input = "XYZ" | ||
| , expected = "XYZ" | ||
| } | ||
| , Case { description = "encode simple" | ||
| , input = "AABBBCCCC" | ||
| , expected = "2A3B4C" | ||
| } | ||
| , Case { description = "encode with single values" | ||
| , input = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" | ||
| , expected = "12WB12W3B24WB" | ||
| } | ||
| ] | ||
|
|
||
| decodeCases :: [Case] | ||
| decodeCases = | ||
| [ Case { description = "decode empty string" | ||
| , input = "" | ||
| , expected = "" | ||
| } | ||
| , Case { description = "decode single characters only" | ||
| , input = "XYZ" | ||
| , expected = "XYZ" | ||
| } | ||
| , Case { description = "decode simple" | ||
| , input = "2A3B4C" | ||
| , expected = "AABBBCCCC" | ||
| } | ||
| , Case { description = "decode with single values" | ||
| , input = "12WB12W3B24WB" | ||
| , expected = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" | ||
| } | ||
| ] | ||
|
|
||
| bothCases :: [Case] | ||
| bothCases = | ||
| [ Case { description = "decode . encode combination" | ||
| , input = "zzz ZZ zZ" | ||
| , expected = "zzz ZZ zZ" | ||
| } | ||
| ] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what is the best position for this exercise, so I think it is ok here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This depends. As it stands this is a very simple exercise, but if some of the more complicated error-handling and number-handling ideas (here exercism/problem-specifications#238) are implemented it would no longer be simple. I put it before
rna-transcriptionbecause at the moment it only requires simple types and notMaybefor error handling.