I am trying to create a function that combines strings given a list of Integers. For example, say the function was given [1,2,3], then the output would be " ***". Basically, each number represents a * with spaces before it. So the number 5 would be " *" which is 4 spaces followed by the *. However, I am given a list and I can't just ++ them all together because the strings mess up the order.
My idea was to start out by taking the first element in the list and send it back as the string recursively. So for [1,2,3] I would send back to the function [2,3] with String = " *". Next, for each element I check if the length of the string -1 is <= the next element (- 1 because 0 is included). In the list that I am giving the function, this will ALWAYS be the case (the list will always be a number from 0-9, increasing, and NO repeats). Then I would ++ the original string to the function call again to make the recursive statement. I did this till there was nothing left. Here is what I've done:
makeStr :: [Integer] -> String -> String
makeStr [] _ = ""
makeStr (x:xs) s
| null xs && s == "" = getStar ((fromIntegral x)) "*"
| null xs && s /= "" = s ++ getStar ((fromIntegral x) - (length s)) "*"
| s == "" = makeStr xs (getStar ((fromIntegral x) - ((length s))) "*")
| length s - 1 <= (fromIntegral x) = s ++ makeStr xs (getStar ((fromIntegral x) - ((length s))) "*")
Note: getStar is a simple function that takes a number and "*" and returns the string with the correct amount of spaces. It has the declaration of getStar :: Int -> String -> String. This function works perfectly, I have tested it numerous times and I really do not believe it is the issue, hence why I did not include it.
An example of getStar function is:
getStar 3 "*"
" *"
some example inputs with expected outputs:
makeStr [1,2,3] ""
" ***"
makeStr [0,2,3] ""
"* **"
makeStr [1,2,3,4] ""
" ****"
makeStr [0,9] ""
"* *"
The output of my program is incorrect for any list over 2 elements.
makeStr [0,1] "" -- correct
"**"
makeStr [1,2,3] "" -- incorrect, should be " ***"
" ** *"
makeStr [1,2,3,4] "" -- incorrect, should be " ****"
" ** * *"
I can't figure out why it is correct for the first 2 elements, then incorrect for anything after. I've traced through it multiple times but it all seems like it should work fine.
Edit Solution:
makeStr :: [Integer] -> String
makeStr [] = ""
makeStr (x:xs)
| x == 0 = "*" ++ makeStr (map (subtract 1) xs)
| x /= 0 = " " ++ makeStr (map (subtract 1) (x:xs))
mergeStars :: String -> String -> Stringthat takes two of these star-lists and produces one that combines stars from both? Hint: you might want to usezipWith.mapover the enumeration[0..maxOfList]with a function that checks if the number is in the input list, and produces'*'or' 'accordingly.[2,2]? and for[3,1]?sinmakeStr (x:xs) sis never used. The type signature could not be justmakeStr :: [Integer] -> Stringinstead ofmakeStr :: [Integer] -> String -> String?