Adding 0-s to a list of until it's length is 8 in Haskell - list

So I have to make a decimal number into binary list like so: intToBitString 4 = [1,0,0].
Which i have done like so:
intToBitString n = reverse (helper n)
helper 0 = []
helper n
| n `mod` 2 == 1 = 1 : helper (n `div` 2)
| n `mod` 2 == 0 = 0 : helper(n `div` 2)
But then I also have to make a function called intToByte, which pads out the list with 0-s until it's length is 8 elements long. (so making it a bytestring) Like this:
intToByte 7 = [0, 0, 0, 0, 0, 1, 1, 1]
I have tried so many things, but they never work. I am a beginner, so I only know the "if" loop the way I showed above, and recursion, but I dont know anything fancy. One of my tries:
intToByte 0 = [0]
intToByte n
| eight n == helper2 n = reverse (helper2 n)
| otherwise = eight n
helper2 0 = []
helper2 n
| n `mod` 2 == 1 = 1 : helper2 (n `div` 2)
| n `mod` 2 == 0 = 0 : helper2 (n `div` 2)
eight n
| length (helper2 n) < 8 = 0 : eight n
| otherwise = helper2 n
I have been working on this for so many hours that i'm getting confused by it. But this is part of an important assignment, so help would be very appreciated!

First of all, you can simplify your code with:
helper2 :: Integral i => i -> [i]
helper2 0 = []
helper2 n = r : helper2 q
where (q,r) = quotRem n 2
Secondly, the above is a big endian representation [wiki]. Indeed, 7 is represented as [1,1,1], whereas 14 is for example represented as [0,1,1,1]. If we want to revers this, we can work with an accumulator:
helper2 :: Integral i => i -> [i]
helper2 = go []
where go rs 0 = rs
go rs n = go (r:rs) q
where (q,r) = quotRem n 2
This thus maps 7 to [1,1,1] and 14 to [1,1,1,0]. But now we still need to add leading zeros. We can do that for example by maintaing the number of elements already added to the list:
eight :: Integral i => i -> [i]
eight = go [] 0
where go rs l 0 = replicate (8-l) 0 ++ rs
go rs l n = go (r:rs) (l+1) q
where (q,r) = quotRem n 2

Padding can be as simple as computing how many additional elements to push to the list and then have those elements produced using the function replicate from the Prelude:
padLeft :: Int -> a -> [a] -> [a]
padLeft n x xs = replicate (n - length xs) x ++ xs
For instance:
> padLeft 8 0 [1, 1, 0]
[0,0,0,0,0,1,1,0]

One approach would be to define a function bits such that bits k converts its argument to a bit string of length k:
bits :: Int -> Int -> [Int]
bits 0 _n = []
bits k n | n < 0 = error "bits: negative"
| n > 2 * m - 1 = error "bits: overflow"
| otherwise = let (i, j) = n `divMod` m in i : bits (k - 1) j
where m = 2 ^ (k - 1)
Your function eight is then easily written as
eight :: Int -> [Int]
eight = bits 8
This gives:
> eight 4
[0,0,0,0,0,1,0,0]
> eight 7
[0,0,0,0,0,1,1,1]

Related

Haskell check integer first element to process an ID number

I'm a newbie in haskell!
I need to write a function that process an ID number. I need to check the first digit of the integer number. If the number is 1 or 3 then the client is male, if the number is 2 or 4 then female. I think I need a helper function which splitting the long integer number to an integer list.
The fuction called szemelyinem, it has one parameter/argument which is a 11 long integer number.
This is the spliting function:
split :: Integral x => x -> [x]
split 0 = []
split x = split (x `div` 10) ++ [x `mod` 10]
In my head the notion is Split the long number then load it to the function, then check the first element in the list and return with one string. But I don't know how to start this :/
I have an example like this:
szemelyinem 40504291247
Result: "female"
This is the first step.
split :: Integral x => x -> [x]
split 0 = []
split x = split (x `div` 10) ++ [x `mod` 10]
This is the second.
rev:: [Integer] -> [Integer]
rev [] = []
rev (h:t) = rev t ++ [h]
This is the third step
nemdel :: [Integer] -> [Integer]
nemdel [] = []
nemdel (h:t) = drop 10 (h:t)
This is the fourth.
listtonumb:: [Integer] -> Integer
listtonumb = foldl addDigit 0
where addDigit num d = 10*num + d
And the last one.
szemelyinem :: Integer -> [Char]
szemelyinem szam =
if listtonumb(nemdel(rev(split szam))) == 1 || listtonumb(nemdel(rev(split szam))) == 3
then "male"
else if listtonumb(nemdel(rev(split szam))) == 2 || listtonumb(nemdel(rev(split szam))) == 4
then "Female"
else error "Bad ID"
I'm sure about that is a complex way to do this shit.

lazy evaluation in infinte list

Hi I have the following code:
let f n (xs) = if n < 0 then f (n-1) (n:xs) else xs
f (-3) [] !! 1
and I expect it to print -4
But it does not print anything and keeps calculation in background.
What is wrong with my code?
Let's step through the evaluation:
f (-3) []
f (-4) [-3]
f (-5) [-4, -3]
f (-6) [-5, -4, -3]
f (-7) [-6, -5, -4, -3]
...
Considering this, what do you expect f (-3) [] !! 1 to be? The value in the index 1 changes each iteration, so there's no way Haskell can know what it is until it reaches the non-recursive case at n >= 0, which never happens.
If you build the list in the other direction, it will work as you expect:
let f n = if n < 0 then n : f (n - 1) else []
> f (-3) !! 1
-4
So here's a pretend integer type:
data Int2 = ... -- 2 bit signed integers [-2, -1, 0, 1]
deriving (Num, Ord, Eq, ...)
Let's imagine that your function was defined on Int2 values:
f :: Int2 -> [Int2] -> [Int2]
f n (xs) = if n < 0 then f (n-1) (n:xs) else xs
This makes it fairly easy to work out what one evaluation step looks like for f n xs:
f 1 xs = xs
f 0 xs = xs
f (-1) xs = f (-2) (-1 : xs)
f (-2) xs = f 1 (-2 : xs) -- because finite signed arithmetic wraps around
and from there we can work out the full value of f n []:
f 1 [] = []
f 0 [] = []
f (-1) [] = f (-2) [-1] = f 1 [-2, -1] = [-2, -1]
f (-2) [] = f 1 [-2] = [-2]
Each computed a value, but note how it took 3 evaluation steps before we got a list out of f (-1) [].
Now see if you can work out how many steps it would take to compute f (-1) [] if it were defined on 4-bit numbers. 8-bit? 32-bit? 64-bit? What if it were using Integer which has no lower bound?
At no point does laziness help you because there's no partial result, only a recursive call. That's the difference between:
lazyReplicate 0 _ = []
lazyReplicate n x = x : lazyReplicate (n - 1) x
and
strictReplicate n x = helper [] n x where
helper xs 0 _ = xs
helper xs n x = helper (x : xs) n x

SML: How to count the number of elements between 5 and 15 of a list

How to calculate the length of a list with a condition on members?
Generally, the following is used to compute the length of a list
(* Compute the length of a list *)
fun length(L) =
if null L then 0
else 1 + length (tl (L));
but how to specify the range of member by counting only between 5 and 10?
If I want to use function foldr for question 1, how to do so?
In the lambda function for List.foldr, you should add 1 to the total if the element matches the condition, but 0 if it doesn't. This way, you can keep track of the number of elements that matches your condition.
val xs = [1,3,5,8,6,9,10,14,13,16,15]
val len = List.foldr (fn (x, t) => (if x > 5 andalso x < 15 then 1 else 0) + t) 0 xs
This is what you get when you run it:
val xs = [1,3,5,8,6,9,10,14,13,16,15] : int list
val len = 6 : int

How to count the number of 1's surrounding a given element in a 2D list with Haskell?

Suppose I have the following nested list:
list =
[[0, 1, 0],
[1, 9, 1],
[1, 1, 0]]
Assuming you are only given the x and y coordinate of 9. How do I use Haskell code to find out how many 1's surrounds the number 9?
Let me clarify a bit more, assume the number 9 is positioned at (0, 0).
What I am trying to do is this:
int sum = 0;
for(int i = -1; i <= 1; i++){
for(int j = -1; j <= 1; j++){
if(i == 0 || j == 0) continue;
sum += list[i][j];
}
}
The positions surrounding (0,0) are the following coordinates:
(-1, -1) (0, -1) (1, -1)
(-1, 0) (1, 0)
(-1, 1) (0, 1) (1, 1)
list = [[0,1,0],[1,9,1],[1,1,0]]
s x y = sum [list !! j !! i | i <- [x-1..x+1], j <- [y-1..y+1], i /= x || j /= y]
--s 1 1 --> 5
Note that I there is no error correction if the coordinates are at the edge. You could implement this by adding more conditions to the comprehension.
A list of lists isn't the most efficient data structure if things get bigger. You could consider vectors, or a Map (Int,Int) Int (especially if you have many zeros that could be left out).
[Edit]
Here is a slightly faster version:
s x y xss = let snip i zs = take 3 $ drop (i-1) zs
sqr = map (snip x) $ snip y xss
in sum (concat sqr) - sqr !! 1 !! 1
First we "snip out" the 3 x 3 square, then we do all calculations on it. Again, coordinates on the edges would lead to wrong results.
Edit: switched to summing surrounding 8 rather than surrounding 4
How often do you just want the surrounding count for just one entry? If you want it for all the entries, lists still perform fairly well, you just have to look at it holistically.
module Grid where
import Data.List (zipWith4)
-- given a grid A, generate grid B s.t.
-- B(x,y) = A(x-1,y-1) + A(x,y-1) + A(x+1,y-1)
-- + A(x-1,y) + A(x+1,y)
-- + A(x-1,y+1) + A(x,y+1) + A(x+1,y+1)
-- (where undefined indexes are assumed to be 0)
surrsum :: [[Int]] -> [[Int]]
surrsum rs = zipWith3 merge rs ([] : init rs') (tail rs' ++ [[]])
where -- calculate the 3 element sums on each row, so we can reuse them
rs' = flip map rs $ \xs -> zipWith3 add3 xs (0 : xs) (tail xs ++ [0])
add3 a b c = a+b+c
add4 a b c d = a+b+c+d
merge [] _ _ = []
-- add the left cell, right cell, and the 3-element sums above and below (zero-padded)
merge as bs cs = zipWith4 add4 (0 : init as) (tail as ++ [0]) (bs ++ repeat 0) (cs ++ repeat 0)
-- given a grid A, replace entries not equal to 1 with 0
onesOnly :: [[Int]] -> [[Int]]
onesOnly = map . map $ \e -> if e == 1 then 1 else 0
list :: [[Int]]
list = [[0, 1, 0]
,[1, 9, 1]
,[1, 1, 0]]
Now you can drop down to ghci to see it work:
*Grid Control.Monad> mapM_ (putStrLn . unwords . map show) list
0 1 0
1 9 1
1 1 0
*Grid Control.Monad> mapM_ (putStrLn . unwords . map show) $ onesOnly list
0 1 0
1 0 1
1 1 0
*Grid Control.Monad> mapM_ (putStrLn . unwords . map show) . surrsum $ onesOnly list
2 2 2
3 5 2
2 3 2

Haskell list comprehension 0's and 1's

I am trying to write a function
row :: Int -> Int -> [Int]
row n v
that returns a list of n integers, all 0's, except for the vth element, which needs to be a 1.
For instance,
row 0 0 = []
row 5 1 = [1,0,0,0,0]
row 5 3 = [0,0,1,0,0]
I am new to Haskell and having a lot of difficulty with this. In particular I can't figure out how to make it repeat 0's. I understand the concept of building a list from let's say [1..n], but I just get [1,2,3,4,5]
Any help with this would be greatly appreciated. Thank you.
Try:
let row n v = map (\x -> if x == v then 1 else 0) [1..n]
Here a "monadic" solution:
row n v = [(v-1, 0), (1, 1), (n-v, 0)] >>= (uncurry replicate)
The replicate function repeats a given value a number of times, e.g. replicate (v-1) 0 gives a list of v-1 zeros. The uncurry is used to modify the replicate in order to accept a tuple instead of two single arguments. The funny operator >>= is the heart of a monad; for lists it is the same as concatMap with flipped arguments.
With a comprehensive list :
row n v = [if x == v then 1 else 0 | x <- [1..n]]
Or using fromEnum (thanks dave4420)
row n v = [fromEnum (x == v) | x <- [1..n]]
This should also work:
row n v = replicate (v-1)­ 0 ++ [1] ++ repl­icate (n-v)­ 0
And yet another solution, recursively building up the list:
row :: Int -> Int -> [Int]
row 0 _ = []
row n 1 = 1 : (row (n-1) 0)
row n m = 0 : (row (n-1) (m-1))
And a more readable one, where zeros are "taken":
row :: Int -> Int -> [Int]
row 0 _ = []
row n m = take (m - 1) zeros ++ [1] ++ take (n - m) zeros
where zeros = (iterate id 0)
A simple recursive loop with two temporary variables c and lst . c is for counting and lst is list which we have to return.
row :: Int -> Int -> [ Int ]
row 0 0 = []
row n v = rowHelp n v 1 [] where
rowHelp n v c lst
| c > n = lst
| v == c = rowHelp n v ( c + 1 ) ( lst ++ [ 1 ] )
| otherwise = rowHelp n v ( c + 1 ) ( lst ++ [ 0 ] )
~
~
the fun with haskell is that it let's you write your program very much the way you would express the algorithm. So try:
row n v = [if (x `mod` v==0) then 1 else 0 | x <- [1..n] ]
At first you create a list from 1,2 to n.
Then you check if the number is divisible by v, if it is, 1 is inserted in the output list, if not 0.
Examples:
> row 0 0
[]
> row 5 1
[1,0,0,0,0]
> row 5 3
[0,0,1,0,0]
> row 15 3
[0,0,1,0,0,1,0,0,1,0,0,1,0,0,1]
HTH Chris
I like to demonstrate a top down approach, based on Chris's solution:
row n v = result
where
result = take n numbers -- our result will have a length of n
numbers = map trans [1,2,..] -- and is some transformation of
-- the list of natural numbers
trans e
| e `mod` v == 0 = 1 -- let every v-th element be 1
| otherwise = 0 -- 0 otherwise
This style emphasizes the idea in functional programming that one writes down what a certain value like row n v is supposed to be, rather than trying to write down what a function does. In reminiscence of a well known joke about the lesser known pragramming language Sartre one could say that in pure functional programming functions do nothing, they just are.