I want to program a function that generates a String. The String contains only 1,0,s and S.
The numbers are binary numbers. Each number is separated through a s. And a number gives the length of the rest of the String. The capital S is the end of the String.
Examples:
func :: Integral a => a -> String
func 1
"1S"
func 3
"110s11s1S"
func 4
"1010s110s11s1S"
My problem is, that I don't know, how I can get the length of the tail ("s1S" -> tail, 11 -> head) and than get the new tail.
My new code:
>toBinary :: Integral a => a -> String
>toBinary 0 = []
>toBinary x
> | mod x 2 == 0 = '0' : toBinary (div x 2)
> | mod x 2 == 1 = '1' : toBinary (div x 2)
>zubinaer :: Integral a => a -> String
>zubinaer x = reverse (toBinary x)
>
>distan :: Integral a => a -> String
>distan n = if n > 0 then hilfsfunktion (n-1) "1S" else []
>
> where
> hilfsfunktion :: Integral a => a -> String -> String
> hilfsfunktion 0 s = s
> hilfsfunktion n s = hilfsfunktion (n-1) (zubinaer(length s + 1) ++ "s" ++ s )
Here my older code: http://hpaste.org/54863
I think you are tackling your problem from the wrong angle. In Haskell, one often thinks of lists. Actually, a String is just a list of Chars. Try to build your function from these bricks:
Write a function toBinary :: Integral a => a -> [Bool] that outputs a binary representation of its parameters. A 1 is True and a 0 is False
You can use map to turn the [Bool] into a String by replacing each boolean by a character 0 or 1.
You can use the syntax [1..n] to generate a list of integers from 1 to n. Use map to generate a list of binary representation strings.
Use intercalate from Data.List to create your string.
Since the tail is defined recursively (ex.: the "tail" of (f 4) is (f 3)) you can get the length of the tail by first getting the tail:
let the_tail = f (n-1) in
then calling the length function on it
length the_tail
Related
I need a program that receives a String containing an octal number and converts it to decimal. If the String contains anything that's not a number from 0 to 8, the function should return a 0.
This is what I got:
octoDec :: [Char] -> Int
octoDec [] = 0
octoDec (x:xs) = ((digitToInt(x)) * 8 ^(length xs)) + octoDec xs
If I enter octoDec ['1','2','3'] I get 83 , which is expected. However, how can I validate the user's without needing another function?
Edit: I've manage to build a function that checks if a number contains only digits between 0 and 7:
isOcto :: [Char] -> Bool
isOcto [] = True
isOcto (x:xs) | (digitToInt(x) > 0) && digitToInt(x) < 7 = isOcto (xs)
|otherwise = False
what i wanted is to merge these two functions into one and return zero to invalid.
If you want octoDec to not only return the result, but also determine whether a result is even possible, return a Maybe Int instead of Int:
octoDec :: [Char] -> Maybe Int
octoDec [] = Just 0
octoDec (x:xs) = do
rest <- octoDec xs
let d = digitToInt x
guard $ d >= 0 && d <= 7
pure $ rest + d * 8^length xs
The guard function from Control.Monad will make the whole do block return Nothing if the condition doesn't hold.
First, you'll want to use Horner's Method to efficiently convert a sequence of digits to a single value.
> foldl (\acc n -> 8*acc + n) 0 (map digitToInt "123")
83
map digitToInt parses the string, and
foldl (\acc n -> 8*acc + n) 0 is a function that evaluates the result of the parse.
horner :: [Int] -> Int
horner = foldl (\acc n -> 8*acc + n) 0
parseString :: [Char] -> [Int]
parseString = fmap digitToInt
octoDec :: [Char] -> Int
octoDec = horner . parseString
However, digitToInt isn't quite right: it can accept digits greater than 7,
> parseString "193"
[1,9,3]
and raises an exception for a value that isn't a digit at all.
> parseString "foo"
[15,*** Exception: Char.digitToInt: not a digit 'o'
We can write a better a function:
octalDigitToInt :: Char -> Maybe Int
octalDigitToInt c | c `elem` "01234567" = Just (digitToInt c)
| otherwise = Nothing
We can use that to convert an octal number into a sequence of digits, using traverse instead of fmap:
parseString' :: [Char] -> Maybe [Int]
parseString' = traverse octalDigitToInt
Valid octal string produce a Just value:
> parseString' "123"
Just [1,2,3]
while invalid strings produce a Nothing value:
> parseString' "193"
Nothing
> parseString' "foo"
Nothing
(Think of traverse as being a function that not only applies a function to a list of values, but only produces a list of results if each application succeeds. More precisely, it's a combination of sequence and fmap:
traverse f = sequence . fmap f
where sequence is the function that "inverts" a value of type [Maybe Int] to a value of type Maybe [Int].)
With a more robust version of parseString, we need to adapt octoDec to handle the possibility that parsing will fail. We do that by using fmap to "lift" horner into the Maybe functor.
octoDec' :: [Char] -> Maybe Int
octoDec' s = fmap horner (parseString' s) -- or octoDec = fmap horner . parseString'
I am writing some code to work with arbitrary radix numbers in haskell. They will be stored as lists of integers representing the digits.
I almost managed to get it working, but I have run into the problem of converting a list of tuples [(a_1,b_1),...,(a_n,b_n)] into a single list which is defined as follows:
for all i, L(a_i) = b_i.
if there is no i such that a_i = k, a(k)=0
In other words, this is a list of (position,value) pairs for values in an array. If a position does not have a corresponding value, it should be set to zero.
I have read this (https://wiki.haskell.org/How_to_work_on_lists) but I don't think any of these methods are suitable for this task.
baseN :: Integer -> Integer -> [Integer]
baseN n b = convert_digits (baseN_digits n b)
chunk :: (Integer, Integer) -> [Integer]
chunk (e,m) = m : (take (fromIntegral e) (repeat 0))
-- This is broken because the exponents don't count for each other's zeroes
convert_digits :: [(Integer,Integer)] -> [Integer]
convert_digits ((e,m):rest) = m : (take (fromIntegral (e)) (repeat 0))
convert_digits [] = []
-- Converts n to base b array form, where a tuple represents (exponent,digit).
-- This works, except it ignores digits which are zero. thus, I converted it to return (exponent, digit) pairs.
baseN_digits :: Integer -> Integer -> [(Integer,Integer)]
baseN_digits n b | n <= 0 = [] -- we're done.
| b <= 0 = [] -- garbage input.
| True = (e,m) : (baseN_digits (n-((b^e)*m)) b)
where e = (greedy n b 0) -- Exponent of highest digit
m = (get_coef n b e 1) -- the highest digit
-- Returns the exponent of the highest digit.
greedy :: Integer -> Integer -> Integer -> Integer
greedy n b e | n-(b^e) < 0 = (e-1) -- We have overshot so decrement.
| n-(b^e) == 0 = e -- We nailed it. No need to decrement.
| n-(b^e) > 0 = (greedy n b (e+1)) -- Not there yet.
-- Finds the multiplicity of the highest digit
get_coef :: Integer -> Integer -> Integer -> Integer -> Integer
get_coef n b e m | n - ((b^e)*m) < 0 = (m-1) -- We overshot so decrement.
| n - ((b^e)*m) == 0 = m -- Nailed it, no need to decrement.
| n - ((b^e)*m) > 0 = get_coef n b e (m+1) -- Not there yet.
You can call "baseN_digits n base" and it will give you the corresponding array of tuples which needs to be converted to the correct output
Here's something I threw together.
f = snd . foldr (\(e,n) (i,l') -> ( e , (n : replicate (e-i-1) 0) ++ l')) (-1,[])
f . map (fromIntegral *** fromIntegral) $ baseN_digits 50301020 10 = [5,0,3,0,1,0,2,0]
I think I understood your requirements (?)
EDIT:
Perhaps more naturally,
f xs = foldr (\(e,n) fl' i -> (replicate (i-e) 0) ++ (n : fl' (e-1))) (\i -> replicate (i+1) 0) xs 0
I am trying to build a function that converts a Decimal(Int) into a Binary number.
Unfortunately other than in java it is not possible to divide an int by two in haskell.
I am very new to functional programming so the problem could be something trivial.
So far I could not find another solution to this problem but
here is my first try :
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = if (mod n 2 == 0) then
do
0:fromDecimal(n/2)
else
do
1:fromDecimal(n/2)
I got an java implementation here which I did before :
public void fromDecimal(int decimal){
for (int i=0;i<values.length;i++){
if(decimal % 2 = 0)
values[i]=true ;
decimal = decimal/ 2;
else {values[i]= false;
} }
}
Hopefully this is going to help to find a solution!
There are some problems with your solution. First of all, I advise not to use do at all, until you understand what do does. Here we do not need do at all.
Unfortunately other than in java it is not possible to divide an int by two in haskell.
It actually is, but the / operator (which is in fact the (/) function), has type (/) :: Fractional a => a -> a -> a. An Int is not Fractional. You can perform integer division with div :: Integral a => a -> a -> a.
So then the code looks like:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = if (mod n 2 == 0) then 0:fromDecimal (div n 2) else 1:fromDecimal (div n 2)
But we can definitely make this more elegant. mod n 2 can only result in two outcomes: 0 and 1, and these are exactly the ones that we use at the left side of the (:) operator.
So we do not need to use an if-then-else at all:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = mod n 2 : fromDecimal (div n 2)
Likely this is still not exactly what you want: here we write the binary value such that the last element, is the most significant one. This function will add a tailing zero, which does not make a semantical difference (due to that order), but it is not elegant either.
We can define an function go that omits this zero, if the given value is not zero, like:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = go n
where go 0 = []
go k = mod k 2 : go (div k 2)
If we however want to write the most significant bit first (so in the same order as we write decimal numbers), then we have to reverse the outcome. We can do this by making use of an accumulator:
fromDecimal :: Int -> [Int]
fromDecimal 0 = [0]
fromDecimal n = go n []
where go 0 r = r
go k rs = go (div k 2) (mod k 2:rs)
You cannot / integers in Haskell – division is not defined in terms of integral numbers! For integral division use div function, but in your case more suitable would be divMod that comes with mod gratis.
Also, you are going to get reversed output, so you can reverse manually it after that, or use more memory-efficient version with accumulator:
decToBin :: Int -> [Int]
decToBin = go [] where
go acc 0 = acc
go acc n = let (d, m) = n `divMod` 2 in go (m : acc) d
go will give you an empty list for 0. You may add it manually if the list is empty:
decToBin = (\l -> if null l then [0] else l) . go [] where ...
Think through how your algorithm will work. It starts from 2⁰, so it will generate bits backward from how we ordinarily think of them, i.e., least-significant bit first. Your algorithm can represent non-negative binary integers only.
fromDecimal :: Int -> [Int]
fromDecimal d | d < 0 = error "Must be non-negative"
| d == 0 = [0]
| otherwise = reverse (go d)
where go 0 = []
go d = d `rem` 2 : go (d `div` 2)
In Haskell, when we generate a list in reverse, go ahead and do so but then reverse the result at the end. The reason for this is consing up a list (gluing new items at the head with :) has a constant cost and the reverse at the end has a linear cost — but appending with ++ has a quadratic cost.
Common Haskell style is to have a private inner loop named go that the outer function applies when it’s happy with its arguments. The base case is to terminate with the empty list when d reaches zero. Otherwise, we take the current remainder modulo 2 and then proceed with d halved and truncated.
Without the special case for zero, fromDecimal 0 would be the empty list rather than [0].
The binary numbers are usually strings and not really used in calculations.
Strings are also less complicated.
The pattern of binary numbers is like any other. It repeats but at a faster clip.
Only a small set is necessary to generate up to 256 (0-255) binary numbers.
The pattern can systematically be expanded for more.
The starting pattern is 4, 0-3
bd = ["00","01","10","11"]
The function to combine them into larger numbers is
d2b n = head.drop n $ [ d++e++f++g | d <- bd, e <- bd, f <- bd, g <- bd]
d2b 125
"01111101"
If it's not obvious how to expand, then
bd = ["000","001","010","011","100","101","110","111"]
Will give you up to 4096 binary digits (0-4095). All else stays the same.
If it's not obvious, the db2 function uses 4 pairs of binary numbers so 4 of the set. (2^8) - 1 or (2^12) - 1 is how many you get.
By the way, list comprehension are sugar coated do structures.
Generate the above patterns with
[ a++b | a <- ["0","1"], b <- ["0","1"] ]
["00","01","10","11"]
and
[ a++b++c | a <- ["0","1"], b <- ["0","1"], c <- ["0","1"] ]
["000","001","010","011","100","101","110","111"]
More generally, one pattern and one function may serve the purpose
b2 = ["0","1"]
b4 = [ a++b++c++d | a <- b2, b <- b2, c <- b2, d <- b2]
b4
["0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"]
bb n = head.drop n $ [ a++b++c++d | a <- b4, b <- b4, c <- b4, d <- b4]
bb 32768
"1000000000000000"
bb 65535
"1111111111111111"
To calculate binary from decimal directly in Haskell using subtraction
cvtd n (x:xs) | x>n = 0:(cvtd n xs)
| n>x = 1:(cvtd (n-x) xs)
| True = 1:[0|f<-xs]
Use any number of bits you want, for example 10 bits.
cvtd 639 [2^e|e<-[9,8..0]]
[1,0,0,1,1,1,1,1,1,1]
import Data.List
dec2bin x =
reverse $ binstr $ unfoldr ndiv x
where
binstr = map (\x -> "01" !! x)
exch (a,b) = (b,a)
ndiv n =
case n of
0 -> Nothing
_ -> Just $ exch $ divMod n 2
Below I have defined a function that converts a list of base-3 digits to the corresponding numerical value. For example:
f "201" = (2 * 3^2) + (0 * 3^1) + (1 * 3^0) = 19
f "12" = 5
f "1202" = 47
f "120221" = 430
Here is a definition using comprehension:
f :: String -> Int
f str = sum (listToFinal (stringToTuples str))
Helper functions:
-- 1) converts "201" to "102"
reverse "str"
-- 2) converts "102" to 102
stringToInt :: String -> Int
stringToInt str = read str :: Int
-- 3) converts 102 to ['1','0','2']
intToList :: Int -> [Int]
intToList 0 = []
intToList x = intToList (x `div` 10) ++ [x `mod` 10]
-- 4) converts "201" to [(1,0),(0,1),(2,2)] using reverse, stringToInt, intToList
stringToTuples :: String -> [(Int,Int)]
stringToTuples str = zip (intToList (stringToInt (reverse str))) [0..]
-- 5) converts [(1,0),(0,1),(2,2)] to [1*3^0, 0*3^1, 2*3^2]
listToFinal :: [(Int,Int)] -> [Int]
listToFinal list = [ x * (3^y) | (x,y) <- list ]
Now I'd like to do it with recursion only (well, using basic & library functions too, of course).
An idea: I was thinking of taking the head of each element in the list and simply multiplying it with 3^(length of string - 1). The only problem is, with each recursive call the power of three would have to decrease by 1, e.g. given:
recursive_version "201" = (2 * 3^2) + (0 * 3^1) + (1 * 3^0)
How to implement this?
Here is a much simpler approach; note that, through the use of foldl, it's only "implicitly" recursive, though. For information, digitToInt is exported by Data.Char.
import Data.Char
import Data.List ( foldl' )
--- horner x xs : the value of polynomial 'xs' at point 'x'
horner :: Int -> [Int] -> Int
horner x = foldl' (\c1 c0 -> c1 * x + c0) 0
-- f s : the integer whose representation in base 3 is string 's'
f :: String -> Int
f = horner 3 . map digitToInt
When you define it recursively, the natural way to decrement the length is trimming the array from the head. For example:
base3 x = base3' x 0 where
base3' (d:ds) v = base3' ds $ v + d * 3 ^ length ds
base3' [] v = v
I want to reverse an Integer in Haskell with recursion. I have a small issue.
Here is the code :
reverseInt :: Integer -> Integer
reverseInt n
| n>0 = (mod n 10)*10 + reverseInt(div n 10)
| otherwise = 0
Example 345
I use as input 345 and I want to output 543
In my program it will do....
reverseInt 345
345>0
mod 345 10 -> 5
reverseInt 34
34
34>0
mod 34 10 -> 4
reverseInt 3
3>0
mod 3 10 -> 3
reverseInt 0
0=0 (ends)
And at the end it returns the sum of them... 5+4+3 = 12.
So I want each time before it sums them, to multiple the sum * 10. So it will go...
5
5*10 + 4
54*10 + 3
543
Here's a relatively simple one:
reverseInt :: Int -> Int
reverseInt 0 = 0
reverseInt n = firstDigit + 10 * (reverseInt $ n - firstDigit * 10^place)
where
n' = fromIntegral n
place = (floor . logBase 10) n'
firstDigit = n `div` 10^place
Basically,
You take the logBase 10 of your input integer, to give you in what place it is (10s, 100s, 1000s...)
Because the previous calculation gives you a floating point number, of which we do not need the decimals, we use the floor function to truncate everything after the decimal.
We determine the first digit of the number by doing n 'div' 10^place. For example, if we had 543, we'd find place to be 2, so firstDigit = 543/100 = 5 (integer division)
We use this value, and add it to 10 * the reverse of the 'rest' of the integer, in this case, 43.
Edit: Perhaps an even more concise and understandable version might be:
reverseInt :: Int -> Int
reverseInt 0 = 0
reverseInt n = mod n 10 * 10^place + reverseInt (div n 10)
where
n' = fromIntegral n
place = (floor . logBase 10) n'
This time, instead of recursing through the first digit, we're recursing through the last one and using place to give it the right number of zeroes.
reverseInt :: Integer -> Integer
reverseInt n = snd $ rev n
where
rev x
| x>0 = let (a,b) = rev(div x 10)
in ((a*10), (mod x 10)*a + b)
| otherwise = (1,0)
Explanation left to reader :)
I don't know convenient way to found how many times you should multiply (mod n 10) on 10 in your 3rd line. I like solution with unfoldr more:
import Data.List
listify = unfoldr (\ x -> case x of
_ | x <= 0 -> Nothing
_ -> Just(mod x 10, div x 10) )
reverse_n n = foldl (\ acc x -> acc*10+x) 0 (listify n)
In listify function we generate list of numbers from integer in reverse order and after that we build result simple folding a list.
Or just convert it to a string, reverse it and convert it back to an integer:
reverseInt :: Integer -> Integer
reverseInt = read . reverse . show
More (not necessarily recursion based) answers for great good!
reverseInt 0 = 0
reverseInt x = foldl (\x y -> 10*x + y) 0 $ numToList x
where
numToList x = if x == 0 then [] else (x `rem` 10) : numToList (x `div` 10)
This is basically the concatenation of two functions : numToList (convert a given integer to a list 123 -> [1,2,3]) and listToNum (do the opposite).
The numToList function works by repeatedly getting the lowest unit of the number (using rem, Haskell's remainder function), and then chops it off (using div, Haskell's integer division function). Once the number is 0, the empty list is returned and the result concatenates into the final list. Keep in mind that this list is in reverse order!
The listToNum function (not seen) is quite a sexy piece of code:
foldl (\x y -> 10*x + y) 0 xs
This starts from the left and moves to the right, multiplying the current value at each step by 10 and then adding the next number to it.
I know the answer has already been given, but it's always nice to see alternative solutions :)
The first function is recursive to convert the integer to a list. It was originally reversing but the re-conversion function reversed easier so I took it out of the first. The functions can be run separately. The first outputs a tuple pair. The second takes a tuple pair. The second is not recursive nor did it need to be.
di 0 ls = (ls,sum ls); di n ls = di nn $ d:ls where (nn,d) = divMod n 10
di 3456789 []
([3,4,5,6,7,8,9],42)
rec (ls,n) = (sum [y*(10^x)|(x,y) <- zip [0..] ls ],n)
Run both as
rec $ di 3456789 []
(9876543,42)