Now I am making code for complicated caesar cipher in Haskell.
I succeeded to make code for normal caesar cipher.
But what I want to do is rotating by key positions again after having used a letter from the string.
For example, AAA with key position 3 will be XUR.
So my problem is after move 3, how can I make next letter will be move 6, and next move 9?
We only need to keep track of the position if I understand it correctly. We can do so by zipWith the [i, i+d ..] list.
So we can construct a function that looks like:
trithemiusEncrypt :: Int -> Int -> String -> String
trithemiusEncrypt i d = zipWith _ [i, i+d .. ]
with _ something we still need to fill in. This function should have type Int -> Char -> Char, so here Int is the "shift" we need to perform on the character. We can thus define this as:
import Data.Char(ord, chr)
trithemiusEncrypt :: Int -> Int -> String -> String
trithemiusEncrypt i d = zipWith f [i, i+d .. ]
where f s c = chr (ca + mod (ord c - ca - s) 26)
ca = ord 'A'
This gives us the expected result:
Prelude> trithemiusEncrypt 3 3 "AAA"
"XUR"
Prelude> trithemiusEncrypt 3 3 "ABC"
"XVT"
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
I need to find all even numbers from String input.
I managed to get all even numbers to list, but I don't understand excactly how can I get sum of those even numbers afterwards.
numbers :: String -> [Int]
numbers [] = []
numbers (l:ls) = if ord l == 48 || ord l == 50 || ord l == 52 || ord l == 54 || ord l == 56
then (ord l - 48): (numbers ls)
else (numbers ls)
So the result would be something like: "abc1234" => 6
You're already pretty there. (ord l - 48) extracts the integer value from the string, so you have to accumulate this value. Or sum up the resulting result (which is basically a function)
The basic recursive loop would be:
numbers :: String -> Int -> Int
Given an empty string and accumulated value -> return accumulated value
Given string (l:ls) not empty and accumulated value ->
if l matches your criteria
numbers ls (accumulated value + (ord l - 48))
else
numbers ls (solely the accumulated value, as `l` doesn't match criteria)
another alternative to write the same
import Data.Char(digitToInt)
sumEvens = sum . map digitToInt . filter (`elem` "2468")
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.
Modification may well be just an addition of 3 to the Char ascii value.
I have gone through several books and can't find a solution off the shelf.
(Returning the Char list can be to a different list variable.)
import Data.Char
shiftAscii :: String -> String
shiftAscii xs = map (chr.(+3).ord) xs
would do what you ask.
It works because map edits each character in the string using the supplied function.
ord converts the Char to its Int value
(+3) shifts the (ascii) by 3
chr converts back to a Char,
so chr.(+3).ord is those three strung together with function composition .
To be more flexible, you could write
shiftAsciiBy :: Int -> String -> String
shiftAsciiBy n = map (chr.(+ n).ord)
notice that shifting the ascii doesn't respect alphabet boundaries, so if you were needing this to do rot13 encoding or similar simple shift, you'd be better off with a hand-rolled shift function that only edits the alphabet
addAscii :: Int -> Char -> Char
addAscii n c | isUpper c = chr $ ((ord c - ord 'A' + n) `mod` 26) + ord 'A'
| isLower c = chr $ ((ord c - ord 'a' + n) `mod` 26) + ord 'a'
| otherwise = c
for example
['A'..'z']
"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"
and we shift just the alphabet ascii:
map (addAscii 5) ['A'..'z']
"FGHIJKLMNOPQRSTUVWXYZABCDE[\\]^_`fghijklmnopqrstuvwxyzabcde"