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] ++ replicate (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.
Related
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]
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
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Given a matrix m,a starting position p1 and a final point p2.
The objective is to compute how many ways there are to reach the final matrix (p2=1 and others=0). For this, every time you skip into a position you decrements by one.
you can only skip from one position to another by at most two positions, horizontal or vertical. For example:
m = p1=(3,1) p2=(2,3)
[0 0 0]
[1 0 4]
[2 0 4]
You can skip to the positions [(3,3),(2,1)]
When you skip from one position you decrement it by one and does it all again. Let's skip to the first element of the list. Like this:
m=
[0 0 0]
[1 0 4]
[1 0 4]
Now you are in position (3,3) and you can skip to the positions [(3,1),(2,3)]
And doing it until the final matrix:
[0 0 0]
[0 0 0]
[1 0 0]
In this case the amount of different ways to get the final matrix is 20.
I've created the functions below:
import Data.List
type Pos = (Int,Int)
type Matrix = [[Int]]
moviments::Pos->[Pos]
moviments (i,j)= [(i+1,j),(i+2,j),(i-1,j),(i-2,j),(i,j+1),(i,j+2),(i,j-1),(i,j-2)]
decrementsPosition:: Pos->Matrix->Matrix
decrementsPosition(1,c) (m:ms) = (decrements c m):ms
decrementsPosition(l,c) (m:ms) = m:(decrementsPosition (l-1,c) ms)
decrements:: Int->[Int]->[Int]
decrements 1 (m:ms) = (m-1):ms
decrements n (m:ms) = m:(decrements (n-1) ms)
size:: Matrix->Pos
size m = (length m,length.head $ m)
finalMatrix::Pos->Pos->Matrix
finalMatrix (m,n) p = [[if (l,c)==p then 1 else 0 | c<-[1..n]]| l<-[1..m]]
possibleMov:: Pos->Matrix->[Pos]
possibleMov p mat = checks0 ([(a,b)|a<-(dim m),b<-(dim n)] `intersect` xs) mat
where xs = movements p
(m,n) = size mat
dim:: Int->[Int]
dim 1 = [1]
dim n = n:dim (n-1)
checks0::[Pos]->Matrix->[Pos]
checks0 [] m =[]
checks0 (p:ps) m = if ((takeValue m p) == 0) then checks0 ps m
else p:checks0 ps m
takeValue:: Matrix->Pos->Int
takeValue x (i,j)= (x!!(i-1))!!(j-1)
Any idea how do I create a function ways?
ways:: Pos->Pos->Matrix->Int
Explore the possible paths in parallel. From the starting position, make all possible moves. Each of the resulting configurations can be reached in exactly one way. Then, from each of the resulting configurations, make all possible moves. Add the counts of the new configurations that can be reached from several of the previous configurations. Repeat that step until there is only one nonzero element in the grid. Cull impossible paths early.
For the bookkeeping which configuration can be reached in how many ways from the initial configuration, the easiest way is to use a Map. I chose to represent the grid as an (unboxed) array, since
they are easier to handle for indexing and updating than lists of lists
they use less space and indexing is faster
The code:
module Ways where
import qualified Data.Map.Strict as M
import Data.Array.Unboxed
import Data.List
import Data.Maybe
type Grid = UArray (Int,Int) Int
type Position = (Int,Int)
type Configuration = (Position, Grid)
type State = M.Map Configuration Integer
buildGrid :: [[Int]] -> Grid
buildGrid xss
| null xss || maxcol == 0 = error "Cannot create empty grid"
| otherwise = listArray ((1,1),(rows,maxcol)) $ pad cols xss
where
rows = length xss
cols = map length xss
maxcol = maximum cols
pad (c:cs) (r:rs) = r ++ replicate (maxcol - c) 0 ++ pad cs rs
pad _ _ = []
targets :: Position -> [Position]
targets (i,j) = [(i+d,j) | d <- [-2 .. 2], d /= 0] ++ [(i,j+d) | d <- [-2 .. 2], d /= 0]
moves :: Configuration -> [Configuration]
moves (p,g) = [(p', g') | p' <- targets p
, inRange (bounds g) p'
, g!p' > 0, let g' = g // [(p, g!p-1)]]
moveCount :: (Configuration, Integer) -> [(Configuration, Integer)]
moveCount (c,k) = [(c',k) | c' <- moves c]
step :: (Grid -> Bool) -> State -> State
step okay mp = foldl' ins M.empty . filter (okay . snd . fst) $ M.assocs mp >>= moveCount
where
ins m (c,k) = M.insertWith (+) c k m
iter :: Int -> (a -> a) -> a -> a
iter 0 _ x = x
iter k f x = let y = f x in y `seq` iter (k-1) f y
ways :: Position -> Position -> [[Int]] -> Integer
ways start end grid
| any (< 0) (concat grid) = 0
| invalid = 0
| otherwise = fromMaybe 0 $ M.lookup target finish
where
ini = buildGrid grid
bds = bounds ini
target = (end, array bds [(p, if p == end then 1 else 0) | p <- range bds])
invalid = not (inRange bds start && inRange bds end && ini!start > 0 && ini!end > 0)
okay g = g!end > 0
rounds = sum (concat grid) - 1
finish = iter rounds (step okay) (M.singleton (start,ini) 1)
I have a series of numbers: 0, 1, 3, 6, 10, 15,...
Basically, you add 1, then you add 2, then add 3, etc.
I have to make a function where I return this series of numbers in a list up to a given number, n. I want to use foldl.
so, series 5 should return [0, 1, 3, 6, 10, 15]
Here is what I have so far:
eachElem n = foldl (+) 0 [0..n]
series n = [x | x <- [(eachElem 0), (eachElem 1)..(eachElem n)]]
Basically, I figured that each element in the list was a foldl operation, and so I made a separate helper function (eachElem) to accomplish this.
However, it is returning a list much larger than what I want.
Eg. series 3 => [0,1,2,3,4,5,6] when it should really return [0,1,3,6]
Any ideas why this is?
scanl is better suited to what you're doing.
Its type is scanl :: (a -> b -> a) -> a -> [b] -> [a] -- its type signature is the same as foldl's, but it returns a list of incremental values, instead of just the final result.
I'll leave the rest as an exercise for you, since this seems like homework. Good luck!
If you are so adamant of using foldl you can do something like
series n = reverse $ foldl f [0] [1..n]
where f xs#(x:_) y = x+y:xs
In ghci
> series 5
[0,1,3,6,10,15]
But problem with foldl is you can not create infinite series.
You can have infinite series like
series = 0:zipWith (+) series [1..]
Then you can do something like
> take (5+1) series
[0,1,3,6,10,15]
I have not tried but you might also use unfoldr or similar concept to build your list.
scanl is the best here, but if you have to use fold try this
testso :: Integral a => a -> [a]
testso n = reverse $ foldl (\acc x -> head acc + x:acc ) [0] [1,2..n]
gives output as testso 10 [0,1,3,6,10,15,21,28,36,45,55].
Your definition of series is wrong.
[(eachElem 0), (eachElem 1)..(eachElem n)] becomes [0, 1, eachElem n] which is actually every number up to eachElem n.
You actually want to do this:
series n = [eachElem x | x <- [0..n]]
the definition
series n = [ x | x <- [(eachElem 0)..(eachElem n)]]
is wrong!
For instance:
because of
eachElem 0 -> 0
eachElem 3 -> 6
series 3 evaluates to
series 3 -> [(eachElem 0)..(eachElem 3)] -> [0..6] -> [0,1,2,3,4,5,6]
You need something like that
series' n = [ eachElem x | x <- [0..n]]
tests:
> let series' n = [ eachElem x | x <- [0..n]]
> let series n = [ x | x <- [(eachElem 0)..(eachElem n)]]
> series' 3
> [0,1,3,6]
> series 3
> [0,1,2,3,4,5,6]
> eachElem 0
> 0
> eachElem 3
> 6
When you write [a,b..c], a is the first element, c is the last element and b is the step, it's the interval between every element in the list and if you omit it, it will be defaulted to 1.
So let's have a look at your code, you do:
[x | x <- [(eachElem 0), (eachElem 1)..(eachElem n)]]
In your list comprehension, x will first take the value (eachElem 0) = 0
Then the next element will be (eachElem 0) + (eachElem 1) = 1
Then the ith elent will be (eachElem 0) + i*(eachElem 1 - eachElem 0) as long as the value is <= (eachElem n)
Hence your result: [0,1..(eachElem n)] which produces [0,1,2,3... and clearly isn't what you expected.
As suggested by amindfv, you should have a look at scanl.
You can cheat :-)
series x = foldl (\xs n -> (n*(n+1) `div` 2):xs) [] [x,(x-1)..0]
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