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
Excel column names are like A, B, C ... AA, AB, AC up to infinite. How can i convert the column name to its column index in Haskell. I can convert index to column but couldnt make the reverse function. Can someone explain me how to write the reverse function of it ? Index to column:
f n = (concatMap sequence $ tail $ iterate (['A'..'Z'] :) []) !! n
Excel columns are simply numbers in Base26, with digits A-Z.
Use readInt from Numeric.
xlColumnToNumberR :: ReadS Int
xlColumnToNumberR = readInt 26 -- There are 26 letters
isAlpha -- From 'Data.Char'
xlValue
where xlValue c = ord (toUpper c) - ord 'A' + 1
xlColumnToNumber :: String -> Maybe Int
xlColumnToNumber n = case xlColumnToNumberR n of
[(x, "")] -> Just x
_ -> Nothing
I'm trying to write a Caesar cipher but with only uppercase alphanumeric. Using ord or chr uses the whole ASCII table. How can accomplish this?
This is what I have so far:
alphabet = ['A'..'Z'] ++ ['0'..'9']
c2I = ord c - ord 'A'
i2C = chr (n + ord 'A')
the basic idea is to use mod to wrap around to the beginning.
Now it's not efficient (but hey you are using the most unsecure cipher so you might not care to much) but I'll show you using just the alphabet and indexing functions:
import Data.List (elemIndex)
alphabet :: [Char]
alphabet = ['A'..'Z'] ++ ['0'..'9']
ith :: Int -> Char
ith i = alphabet !! j
where j = i `mod` length alphabet
index :: Char -> Int
index c = case c `elemIndex` alphabet of
Just i -> i
Nothing -> error "not inalphabet"
encode :: Int -> String -> String
encode n xs = [ ith $ index x + n | x <- xs ]
this will give you
λ> encode 3 "ABCXYZ012789"
"DEF012345ABC"
now you probably will want to find a way using ord and chr - both works if you make a case distinction between A-Z and 0-9, because the ranges are:
65-90 for A-Z
48-57 for 0-9
so you cannot take a one formula without to many tricks
You should try but it's more math from here (you'll probably want something like ord c - ord 'A' for letters and 26 + ord c - ord '0' for digits to get it in the range 0-35 first.
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