Help to solve simple problem !

View: New views
3 Messages — Rating Filter:   Alert me  

Help to solve simple problem !

by Aneto :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi ! I am beginner in Haskell and have problems with this problem:
compress :: Eq a => [a] -> [(a, Int)]
If you have string "AAABCCC" it transforms it to : {A, 3} {B,1} {C,3}

Could you help me with it ?
Thank you in advance !

Re: Help to solve simple problem !

by Ezra Lalonde :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The following program should work:

=======compress.hs=============
toList :: (Eq a) => [a] -> [[a]]
toList [] = []
toList x = start : toList end
    where (start, end) = span (==(head x)) x

toTuple :: [a] -> (a, Int)
toTuple x = (head x, length x)

compress :: Eq a => [a] -> [(a, Int)]
compress x = map toTuple $ toList x
=============================

The important thing to understand here, is the "span" function from the Prelude, and apply it recursively.
*Main> span (=='A') "AAABCC"
("AAA","BCC")
*Main> span (=='h') "hhhaskell"
("hhh","askell")

I've used a function "toList" to separate each part of the string into a separate element of a list:
*Main> toList "AAABCC"
["AAA","B","CC"]
*Main> toList "EEEZZZRRAAAA!!"
["EEE","ZZZ","RR","AAAA","!!"]

From there, "toTuple" takes the first letter of the string, and puts it with its length in a tuple:
*Main> toTuple "EEE"
('E',3)
*Main> toTuple "EEEEE"
('E',5)

Because of how it's defined, we also get the following:
*Main> toTuple "Ezra"
('E',4)

But that won't matter if we only use it after "toList", as in "compress".

Also, I've used your type signature for my solution, not your example output; if you want it to be displayed like that, you'll have to write your own function for printing.

This solution is probably not optimal, but it's a start.

Hope that helps,
Ezra

Aneto wrote:
Hi ! I am beginner in Haskell and have problems with this problem:
compress :: Eq a => [a] -> [(a, Int)]
If you have string "AAABCCC" it transforms it to : {A, 3} {B,1} {C,3}

Could you help me with it ?
Thank you in advance !

Re: Help to solve simple problem !

by Eduard Sergeev :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Aneto wrote:
compress :: Eq a => [a] -> [(a, Int)]
If you have string "AAABCCC" it transforms it to : {A, 3} {B,1} {C,3}
Basically you need to "group" equal elements of the list first and then transform every group (which is a list of equal elements) to the tuple of (first_element , the_ length_of_the_group). All necessary functions can be found in Prelude and Data.List:

import Data.List

compress :: Eq a => [a] -> [(a, Int)]
compress xs = map (\g -> (head g, length g)) (group xs)


PS You can express it somehow nicer with arrows thought:

import Data.List
import Control.Arrow

compress :: Eq a => [a] -> [(a, Int)]
compress = map (head &&& length) <<< group