user2863323
user2863323

Reputation: 351

String split into 6 parts every character in Haskell

I want to be able to split a string into 6 separate strings every character.

So for example IAMABADPROGRAMMER

would result in: IDA, APM, MRM, AOE, BGR, AR

Is there a haskell function to do this?

Thanks

Upvotes: 2

Views: 1720

Answers (2)

itsbruce
itsbruce

Reputation: 4843

I was sure this could be done with list comprehensions and nothing beyond the basic functions in Prelude...

    groupNth :: Int -> [a] -> [[a]]
    groupNth n [] = []
    groupNth n xs = take n $ [ y | y <- everyNth xs ] : groupNth n (tail xs)
            where
            everyNth [] = []
            everyNth l@(y:ys) = y : everyNth (drop n l)

Seems to work and I think is more efficient than using transpose.

Upvotes: 2

bheklilr
bheklilr

Reputation: 54078

There isn't a function to do it already, but it can be written quite easily:

import Data.List (transpose)

chunk :: Int -> [a] -> [[a]]
chunk _ [] = []
chunk n xs = first : chunk n rest where (first, rest) = splitAt n xs

splitSkip :: Int -> [a] -> [[a]]
splitSkip n xs = transpose $ chunk n xs

main :: IO ()
main = print $ splitSkip 6 "IAMABADPROGRAMMER"

My first intuition was to generalize this to all lists, not just lists of Chars. When you remember that the type [String] is the same as [[Char]], you see that you end up with a 2D matrix of Chars, where if you went down each column going left-to-right, you would get the original list back. Well, that's the same as transposing the matrix and going down each row top-to-bottom, which is the same as just splitting the original list into chunks of n elements first. At this point, I had the solution, just worked backwards. I wrote a quick function to chunk a list, then used the transpose function from Data.List to finish it off.

Upvotes: 3

Related Questions