Haskell. Numbers in binary numbers. words - haskell

import Data.Char
blockCode :: S
lett2num :: Char -> Int
lett2num y
| (or
num2bin :: Int -> [Int]
num2bin n: negative number"
where n2b 0 = []
n2b n = n `mod` 2 : n2b (n `div` 2)

You can use concatMap show to transform a list into a string:
Main> num2bin 8
[0,0,0,1]
Main> concatMap show $ num2bin 8
"0001"
but note that your function's output is reversed.
To do everything in one go, do
num2bin :: Int -> String
num2bin n
| n >= 0 = concatMap show $ reverse $ n2b n
| otherwise = error "num2bin: negative number"
where n2b 0 = []
n2b n = n `mod` 2 : n2b (n `div` 2)

Function converts integer to binary:
num2bin :: (Integral a, Show a) => a -> String
num2bin 0 = "0"
num2bin 1 = "1"
num2bin n
| n < 0 = error "Negative number"
| otherwise = num2bin (n `div` 2) ++ show (n `mod` 2)

Related

Output of a list of Maybe Int with Just in every element in Haskell

I have this function which takes an integer n and returns a list of type Maybe Int, containing the unique prime factors. I don't understand why it returns them with Just inside every element of the list.
I expect an output like this:
primeFactors 75 = Just [3,5]
But I have one that looks like this:
primeFactor 75 = [Just 5,Just 3,Just 1]
Here is my code:
divides :: Int -> Int -> Bool
divides m n = rem m n == 0
transform :: Int -> Int
transform n = (n*2) + 1
isComposite :: Int -> Bool
isComposite n = foldl (||) (divides n 2) (map (divides n) (map (transform) [1..(div n 4)]))
isPrime :: Int -> Bool
isPrime n
| n <= 0 = error "Makes no sense"
| n < 4 = True
| otherwise = not (isComposite n)
primeFactors :: Int -> [Maybe Int]
primeFactors 0 = [Nothing]
primeFactors n = primeFactors2 n ((div n 2)+1)
primeFactors2 :: Int -> Int -> [Maybe Int]
primeFactors2 n 0 = []
primeFactors2 n x
| divides n x && isPrime x = Just x:primeFactors2 n (x-1)
| otherwise = primeFactors2 n (x-1)
Here is a version of your code that I think will do what you want:
primeFactors :: Int -> Maybe [Int]
primeFactors n
| n <= 0 = Nothing
| otherwise = Just $ primeFactors2 n n
primeFactors2 :: Int -> Int -> [Int]
primeFactors2 n p
| n <= 1 || p <= 1 = []
| divides n p && isPrime p = p : primeFactors2 (n `div` p) p
| otherwise = primeFactors2 n (p-1)
isPrime :: Int -> Bool
isPrime n
| n <= 1 = False
| otherwise = not (isComposite n)
isComposite :: Int -> Bool
isComposite n =
any (divides n) [2..n-1]
divides :: Int -> Int -> Bool
divides m n =
rem m n == 0
Please note that (for clarity's sake I hope) I did remove some of your optimizations and made a major change: this one will report Just [2,2] as prime-factors for 4
(IMO you want product <$> primeFactors n == Just n).
If not (as your example indicates) it shouldn't be too hard to fix this (just take your version).
Anyway the only really interesting contribution is how primeFactor handles primeFactors2 to get you the Maybe result.

Convert to binary notation in Haskell

Is there a better way to check n and c in this code, maybe with pattern matching or something more Haskell-like?
toBin :: Int -> Int -> [Int]
toBin n c
| n < 0 = []
| c <= 0 = []
toBin n c = toBin (n `div` 2) (c - 1) ++ [n `mod` 2]
Well, they're both boolean expressions, so you can combine them with ||
toBin n c | n < 0 || c <= 0 = []
It is better here to work with an accumulator, which prevents making O(n) appends that result in an O(n2) algorithm in your code:
toBin :: Int -> Int -> [Int]
toBin = go []
where go rs n c
| n < 0 || c <= 0 = rs
| otherwise = go (r:rs) q (c-1)
where (q,r) = quotRem n 2
We here thus start with an empty list, and each time prepend the list with the next remainder until the number is zero, or the number of bits is 0.

Haskell Recursion with Chars

Write a recursive Haskell function
makeString :: Int -> Char -> Char -> String
such that makeString n ch1 ch2 returns a string as follows:
When n is positive, the string has length 3n-2 and contains n copies
of ch1, each copy separated by two copies of ch2.
When n is less than or equal to zero, the string is the empty string.
For example, the function has the following behavior:
Main > makeString 5 'a' '!'
"a!!a!!a!!a!!a"
Main > makeString 1 'a' '!'
"a"
Main > makeString 10 '6' '#'
"6##6##6##6##6##6##6##6##6##6"
So far I have:
makeString :: Int -> Char -> Char -> String
makeString n ch1 ch2
|n <= 0 = [ ]
|otherwise = ch1: makeString(3*n-2)(ch2)(ch1)
Main> makeString 5 'a' '!'
"a!a!a!a!a!a!a!a!a!a!a!a!a!a!a!a!a!a!a!a"
A quick and dirty implementation
module Test where
merge :: [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x : y : y : merge xs ys
makeString :: Int -> Char -> Char -> String
makeString 0 _ _ = []
makeString n ch1 ch2 = take ((3 * n) - 2) $ merge (replicate (3 * n) ch1) (replicate (3 * n) ch2)
The replicate creates long enough lists for merge to do its work. Works for all positive ns
Here is my solution:
makeString :: Int -> Char -> Char -> String
makeString n ch1 ch2
| n <= 0 = ""
| n == 1 = [ch1]
| otherwise = [ch1, ch2, ch2] ++ makeString (n-1) ch1 ch2

Haskell function to check if substring "100" is present in the binary expansion of a decimal number

Define a function nohundred :: Int -> Int such that for a positive number n nohundred n is the nth positive number such that "100" does not occur as a substring in its binary expansion.
decToBin :: Int -> [Int]
decToBin x = reverse $ decToBin' x
where
decToBin' :: Int -> [Int]
decToBin' 0 = []
decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a
check :: [Int] -> Bool
check (z:zs)
|((z == 1) && (head (zs) == 0) && (head (tail zs) == 0)) = True
| otherwise = check zs
binToDec :: [Int] -> Int
binToDec l = sumlist (zipWith (*) (iterate f 1) (reverse l))
where
sumlist :: [Int] -> Int
sumlist [] = 0
sumlist (x:xs) = x + (sumlist xs)
f :: Int -> Int
f j = (2 * j)
nohundred :: Int -> Int
nohundred n = if ((check fun) == True) then (binToDec (fun)) else (nohundred (n+1))
where
fun = decToBin n
The above code gives error :-
*Main> nohundred 10
*** Exception: Prelude.head: empty list...
The desired output is 14.
*Main> nohundred 100
100
The desired output is 367...
Can anyone suggest the cause of error?
This function is partial:
check (z:zs)
|((z == 1) && (head (zs) == 0) && (head (tail zs) == 0)) = True
| otherwise = check zs
When called with a one- or two-element list, the first check will call head on an empty list. Additionally, it does not cover the empty-list case. The idiomatic way to write this is:
check (1:0:0:zs) = True
check (z:zs) = check zs
check [] = False
Additionally, your nohundred function takes a number and finds the next higher non-hundred number; but you want the nth non-hundred number, which is a very different thing.

Haskell about how to separate the last number from a string number

I have a question about haskell in seperation the last number from a string number. For example, input is (1234), output is (123,4)
I have done a programming, but it does not work.
toDigits :: Int -> [Int]
toDigits n
| n <= 0 = []
| otherwise = toDigits(n `mod` 10) ++ [n `div` 10]
You just have div and mod swapped.
toDigits n | n <= 0 = []
| otherwise = toDigits (n `div` 10) ++ [n `mod` 10]

Resources