how can i convert a string to tuple

Viewed 154

hello we have to create a code with turns for example "1T3e1s1t" into [(1,'T'),(3,'e'),(1,'s'),(1,'t')]

here is my code

unformat :: String -> [(Int, Char)]
unformat [] = []
unformat (x:xs) = [(unformat' + 1, x)] ++ unformat xss
  where 
    unformat' = length (takeWhile (== x)xs)
    xss = drop unformat' xs

it works but the output is "1T3e" -> [(1,'1'),(1,'T'),(1,'3'),(1,'e')] other than the takeWhile - drop function i get errors. The usage of the function replicate ive tried as well but with the wrong output again

unformat :: String -> [(Int, Char)]
unformat [] = []
unformat (x:xs) = (replicate (fst x) (snd x)) ++ unformat xs

id appreciate any kind of help sincerely

2 Answers

You can pattern-match also by multiple elements at the beginning of a list (like a:b:xs):

module Main where

import Data.Char

main = print $ unformat "1T3e1s1t" -- [(1,'T'),(3,'e'),(1,'s'),(1,'t')]

unformat :: String -> [(Int, Char)]
unformat (i:c:xs) = (digitToInt i, c) : unformat xs
unformat _ = []

Data.Char.digitToInt converts '0' to 0 and 'f' to 15, for example.

Here my solution with foldl. In each step we remember prev chars as a Jsut c if it's the first item of tuple or Nothing if it's second item of tuple.

module Main where

import Data.Char

main :: IO ()
main = print $ unformat "1T3e1s1t"

unformat :: String -> [(Int, Char)]
unformat s = snd $ foldl opr (Nothing , []) s
  where
    opr (prev, acc) c = case prev of
      Just n -> (Nothing, acc ++ [(digitToInt n, c)])
      Nothing -> (Just c, acc)

The output will be:

[(1,'T'),(3,'e'),(1,'s'),(1,'t')]
Related