Reputation: 33
I'm trying to convert an integer from decimal integer to a string based on base 4, but my unfoldr doesn't work and I'm not sure why or how to replace it. I can't use imports either. Please help me fix this.
dec2Base4 :: Int -> String
dec2Base4 = map i2c . reverse . unfoldr decomp
where
decomp n = if n == 0 then Nothing else Just(n `mod` 4, n `div` 4)
i2c i = if i == 0 then '0' else if i == 1 then '1' else if i == 2 then '2' else '3'
Example: dec2Base4 10-> "22"
Upvotes: 1
Views: 203
Reputation: 4733
Your code is basically OK, but it would need you to import the unfoldr
function from the Data.List
package.
The fact that you are banned from using import
clauses might just mean that the powers that be want you to use plain recursion.
Unfortunately, recursion will naturally produce the least significant digit (rightmost digit) first, because this rightmost digit is essentially mod n 4
. You will have to use the reverse
function to correct that, just like in your library-based code.
For example, without the help of any non-Prelude library functions, the dec2Base4
function can be written like this:
dec2Base4 :: Int -> String
dec2Base4 n
| (n < 0) = '-' : (reverse (auxStr (-n)))
| (n == 0) = "0"
| otherwise = reverse (auxStr n) -- when n > 0
where
i2c i = "0123" !! i
auxStr 0 = ""
auxStr n = let (q,r) = (divMod n 4) in (i2c r) : (auxStr q)
unitTest :: Int -> IO ()
unitTest n = do
let res = dec2Base4 n
putStrLn $ "Result for " ++ (show n) ++ " is: " ++ res
main = do
let testList = [0,11,2051,-2051]
mapM_ unitTest testList
Result for 0 is: 0
Result for 11 is: 23
Result for 2051 is: 200003
Result for -2051 is: -200003
Upvotes: 1