2

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

  • `fst x` and `snd x` makes not much sense: `x` is a `Char` here, not a 2-tuple. – Willem Van Onsem Jan 19 '22 at 21:14
  • 2
    Your attempts (if indeed they are your own) are solving a different problem, namely to turn `"Teeest"` into `[(1,'T'),(3,'e'),(1,'s'),(1,'t')]`. – leftaroundabout Jan 19 '22 at 23:11
  • 1
    Someone asked this same question, with the same example string, a few days ago. I can't find it, though, to know whether it's the same author or someone else taking the same class or what. Probably deleted, and probably by a different author, I guess, since it included more details about the problem - I remember a guarantee that none of the characters to be encoded would be digits. – amalloy Jan 20 '22 at 00:54
  • @amalloy https://stackoverflow.com/questions/70763016/run-length-encoding-string-to-tuple – Will Ness Jan 20 '22 at 08:08
  • @WillNess Thanks! How did you find this? I usually have a terrible time finding such questions: once it's deleted, Google and Stack Overflow's search both can't find it at all. – amalloy Jan 20 '22 at 10:04
  • @amalloy in my Chrome browsing history. searched for "run". (remembered it talked about "run-length encoding"). there is also https://stackoverflow.com/tools where you can see some "Recently Deleted" posts but it only goes back an hour or so and there is no search, so it's not really helpful. you can search for _your own_ deleted posts with `deleted:1` of course so if you had an answer that got deleted with the question, you can find it that way. – Will Ness Jan 20 '22 at 11:05

2 Answers2

4

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.

j1-lee
  • 13,764
  • 3
  • 14
  • 26
1

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')]
S4eed3sm
  • 1,398
  • 5
  • 20