Search code examples
listhaskellfold

Given a string, get list of tuples (char, how many times the character goes in a row) - Haskell


For example: ʺaaaabbaabʺ->[(‘a’,4),(‘b’,2),(‘a’,2),(‘b’,1)] Its need to be done using FOLDR through one pass of the list, without using (++).

Here what I have so far

task2 (x:xs) = foldr (\c [(symbol, count)] -> if symbol == c then [(symbol, count+1)] else [(symbol, count)]) [(x, 1)] xs

The problem is I don't really understand how to make it go to the next element of the list after 'if' statement is False


Solution

  • Writing the step function as an inline lambda expression is probably not the best possible move. It can be made to work, but that leads to a very long line of code.

    It is easier to write the step function separately, like this:

    task2 :: String -> [(Char,Int)]
    task2 cs = foldr stepFn [] cs
      where
        stepFn c      []          =  [(c,1)]  -- simple case
        stepFn c ((c1,n1) : ps)   =           -- please try to write the rest ...
    

    if (c == c1) then (c1,1+n1) : ps else (c,1) : (c1,n1) : ps

    Testing:

    $ ghci
     GHCi, version 8.8.4: https://www.haskell.org/ghc/  :? for help
     λ> 
     λ> :load q69871708.hs
     [1 of 1] Compiling Main             ( q69871708.hs, interpreted )
     Ok, one module loaded.
     λ> 
     λ> task2 "aaaabbaabrrrzz"
     [('a',4),('b',2),('a',2),('b',1),('r',3),('z',2)]
     λ> 
     λ> task2 "a"
     [('a',1)]
     λ> 
     λ> task2 ""
     []
     λ>