Skip to content

Implementing rail-fence-cipher #627

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

Merged
merged 3 commits into from
Dec 4, 2017
Merged

Implementing rail-fence-cipher #627

merged 3 commits into from
Dec 4, 2017

Conversation

Average-user
Copy link
Member

@Average-user Average-user commented Nov 29, 2017

I'm not sure about the types on src/RailFenceCipher.hs

Should I change them to f :: Int -> String -> String or change the ones from the tests?

@Average-user
Copy link
Member Author

Or maybe change the example to:

encode' :: (Ord a) => Int -> [a] -> [a]
encode' n xs = concat [[a | (a, b) <- zip xs c, b == i] | i <- [1..n]]
  where c = cycle $ [1..n] ++ [n-1,n-2..2]

encode :: Int -> String -> String
encode = encode'

decode :: Int -> String -> String
decode n xs = map snd $ sort $ zip (encode' n [0..length xs - 1]) xs

Copy link
Member

@petertseng petertseng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems good, seems good. I think I have an answer to your question, and a question to ask.


import Data.List (sort)

encode :: (Ord a) => Int -> [a] -> [a]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you explain to me why (Ord a) => necessary? I am not seeing why, but I may have just missed it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it isn't, I think it was from a previous version

Copy link
Member Author

@Average-user Average-user Nov 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow my bad there, seems like in the sort is needed, cause it takes on count the element of the pairs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I leave it as it is? Or use sortBy?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to sum up, I think that there are 2 options:

decode :: Int -> [a] -> [a]
decode n xs = map snd $ sortBy (compare `on` fst) zippedL
  where zippedL = zip (encode n [0..length xs - 1]) xs

or what we already have.

Copy link
Member

@petertseng petertseng Nov 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, because you are using sort in decode.

In contrast to the stub, where I argued that we only need show the student what was specified by the problem description, here in the example I would in fact prefer not to add constraint that isn't necessary. Because the example is doing well by expanding from String to some other type. But if it's stopping at (Ord a) then it's only going halfway! It should go all the way!

Thus, let us use sortBy here!

encode n xs = concat [[a | (a, b) <- zip xs c, b == i] | i <- [1..n]]
where c = cycle $ [1..n] ++ [n-1,n-2..2]

decode :: (Ord a) => Int -> [a] -> [a]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you explain to me why (Ord a) => necessary? I am not seeing why, but I may have just missed it.

same question

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same answer

@@ -0,0 +1,7 @@
module RailFenceCipher (encode, decode) where

encode :: Int -> [a] -> [a]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you ask whether to change this. I would use String here simply because that is all tests will use, and it's fine if students realise it can be generalised and therefore change it back to [a]. I would therefore also not change the example, minus the comment I make on it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why make it less general when it works fine with other types?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I see is that https://github.com/exercism/problem-specifications/blob/master/exercises/rail-fence-cipher/description.md only talks about working with strings, thus that is the extent of the problem being specified. Therefore, any function that I write that adheres to this specification need only operate with strings. It is of course great if it works with other types. I imagine most solutions will. The possible complaint with putting [a] here is that "why is this stub asking for more than the problem specification is asking for?" the possible complaint with putting String is "this stub is unnecessarily restricting this function to only work with the specification, but it could do more"

It's not a perfect analogue, but there are text like https://github.com/exercism/haskell/blob/master/exercises/leap/HINTS.md or https://github.com/exercism/haskell/blob/master/exercises/series/HINTS.md that we can add.

I don't remember right now whether this track has a policy or other examples of either choice ("give minimal signature that satisfies the specification and let students expand" or "give the most general signature that a reasonable solution should be able to achieve") and I can't go looking for examples now, so I make my recommendation based on what I can see now, but I would change if there is an example of something we have done in the past.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I thing with Int -> String -> String would be just fine, afterall

encode :: Int -> [a] -> [a]
encode = "You need to implement this function!"

decode :: Int -> [a] -> [a]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you ask whether to change this. I would use String here simply because that is all tests will use, and it's fine if students realise it can be generalised and therefore change it back to [a]. I would therefore also not change the example, minus the comment I make on it.

same comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh ok, dint read this before

@@ -0,0 +1 @@
## pls regenerate this!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remind myself to regenerate.

module RailFenceCipher (encode, decode) where

encode :: Int -> [a] -> [a]
encode = "You need to implement this function!"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget error!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops!

encode = "You need to implement this function!"

decode :: Int -> [a] -> [a]
decode = "You need to implement this function!"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget error!

same

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops!

same :(

Copy link
Member

@petertseng petertseng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's do it.

@petertseng petertseng merged commit c0f56ed into exercism:master Dec 4, 2017
@Average-user
Copy link
Member Author

let's do it.

Do what?

@Average-user
Copy link
Member Author

ohh, I see.

@@ -0,0 +1,20 @@
name: rail-fence-cipher
version: 1.1.0.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my mistake. it was 1.0.1 not 1.1.0. Fixed in #634

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants