Kappa123
Kappa123

Reputation: 351

Shortening a string in Haskell with a condition

Chomp will take the longest amount of repeated characters from a string and one will limit this to 9, e.g. if given the string "aaaaabbbcc" , the answer would be "aaaaa"

I need to define a function, runs, which will do a similiar thing but it will put the string into separate lists, e.g. if the given string is "aaaaabbbccc" , the answer would be ["aaaaa","bbb","cc"], and I need to use the munch function to do this.

The condition of 9 characters applies too, so if the given string is "aaaaaaaaaa" , the answer would be ["aaaaaaaaa","a"]

I've not actually got any implementation apart from something that I found which does pretty much does the same thing without the limit of 9 characters:

runs :: String -> String
runs x = group x

I thought of 2 ways of doing this, but I have no clue on the actual implementation, with one being to run the munch function for however many unique characters there are, i.e if there is an x amount of a , b , c in the given string, it would run 3 times, and then put those lists together into one list.

Another way that I thought of is to use guards. If the number of any single character in the given string is 9 or less, then just use the group function, otherwise, shorten it down using munch, or something like that.

Is anyone able to tell me if the two ideas I mentioned would work at all or suggest an alternative and how to get started? I'm a bit lost.

Upvotes: 1

Views: 611

Answers (3)

fp_mora
fp_mora

Reputation: 714

The basic strategy here is to take each unique list element to identify successive list elements that are identical. This let you have list elements in any mixed order. There are three functions but no imports.

The first function is rd which creates the list of unique elements.

The second function, t9 is because there might be over 18 of the same elements. t9 will create 9 character long list segments of identical elements with the remainder as the last list (string).

The final, unnamed function uses rd to compile lists of all elements matching each unique elements. It uses t9 to create segments of 9 elements.

l = "bbbbbbbbbaaaaaaaaaaaadddadaaaaaaacccccccccc"
rd [] = []; rd (x:xs) | elem x xs = rd xs | otherwise = x:rd xs
t9 [] = []; t9 xs = [take 9 xs] ++ t9 (drop 9 xs)
[ t | f <- rd l, s <- [[ g | g <- l, f == g ]], t <- t9 s ]

["bbbbbbbbb","dddd","aaaaaaaaa","aaaaaaaaa","aa","ccccccccc","c"]

Upvotes: 0

karakfa
karakfa

Reputation: 67507

here is another approach

define a split function to break list at fixed size chunks

splitn :: Int -> [a] -> [[a]]
splitn _ [] = []
splitn n x = take n x : (splitn n $ drop n x)

now you can write your function as

runs =  concatMap (splitn 9) . group

Upvotes: 1

Lorenzo
Lorenzo

Reputation: 2210

A quick google gives you exactly what you're looking for.

https://codereview.stackexchange.com/questions/158183/string-splitting-function-in-haskell

If it works consider upvoting their answer as I only copied a link

Upvotes: 0

Related Questions