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]
Related
So suppose we want to produce the list [0, 1, -1, 2, -2, ...in Haskell.
What is the most elegant way of accomplishing this?
I came up with this solution:
solution = [0] ++ foldr (\(a,b) c->a:b:c) [] zip [1..] $ map negate [1..]
But I am sure there must be a better way.
This seems like the kind of thing that comprehensions are made for:
solution = 0 : [y | x <- [1..], y <- [x, -x]]
With iterate
Perhaps a more elegant way to do this, is by using iterate :: (a -> a) -> a -> [a] with a function that generates each time the next item. For instance:
solution = iterate nxt 0
where nxt i | i > 0 = -i
| otherwise = 1-i
Or we can inline this with an if-then-else:
solution = iterate (\i -> if i > 0 then -i else 1-i) 0
Or we can convert the boolean to an integer, like #melpomene says, with fromEnum, and then use this to add 1 or 0 to the answer, so:
solution = iterate (\i -> fromEnum (i < 1)-i) 0
Which is more pointfree:
import Control.Monad(ap)
solution = iterate (ap subtract (fromEnum . (< 1))) 0
With (<**>)
We can also use the <**> operator from applicate to produce each time the positive and negative variant of a number, like:
import Control.Applicative((<**>))
solution = 0 : ([1..] <**> [id, negate])
How about
concat (zipWith (\x y -> [x, y]) [0, -1 ..] [1 ..])
or
concat (transpose [[0, -1 ..], [1 ..]])
?
How about:
tail $ [0..] >>= \x -> [x, -x]
On a moment's reflection, using nub instead of tail would be more elegant in my opinion.
another primitive solution
alt = 0 : go 1
where go n = n : -n : go (n+1)
You could also use concatMap instead of foldr here, and replace map negate [1..] with [0, -1..]:
solution = concatMap (\(a, b) -> [a, b]) $ zip [0, -1..] [1..]
If you want to use negate instead, then this is another option:
solution = concatMap (\(a, b) -> [a, b]) $ (zip . map negate) [0, 1..] [1..]
Just because no one said it:
0 : concatMap (\x -> [x,-x]) [1..]
Late to the party but this will do it as well
solution = [ (1 - 2 * (n `mod` 2)) * (n `div` 2) | n <- [1 .. ] ]
I want to write a function that uses list comprehensions to generate a list of lists that works like this:
makeList 3 == [[1],[1,2],[1,2,3]]
makeList 5 == [[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]]
makeList (-2) == []
I end up with this solution, but It not gives me what it needs from the question obviously:
let makelist x = [x | x <- x, y <- [1..x]]
So if I enter this
Prelude> makelist [3]
the output will shows like this:
[3,3,3]
I wanted to be a list in list first then I want it to be increased. Thank you for help!
Let's try generating an inner list first, for some limit m:
> let inner m = [1..m]
> inner 5
[1,2,3,4,5]
Now, observe that your outer list, for some limit n, is [inner 1, inner 2, inner 3, ..., inner n], or, in list comprehension form:
> let outer n = [inner m | m <- [1..n]]
> outer 3
[[1], [1,2], [1,2,3]]
so we can combine the two into the single list comprehension expression:
> let makeList n = [[1..m] | m <- [1..n]]
> makeList 4
[[1],[1,2],[1,2,3],[1,2,3,4]]
I propose you this:
make_list n = [ [1..m] | m <- [1..n] ]
However there's something strange in your first attempt:
make_list x = [x | x <- x, y <- [1..x]]
there you put x for every purpose. It just feels wrong.
A recursive version based in list generation as well,
makeList' :: Int -> [[Int]]
makeList' n
| n < 1 = []
| otherwise = [1..n] : makeList' (n-1)
makeList :: Int -> [[Int]]
makeList n = reverse $ makeList' n
makeList' returns the desired outcome in reverse order.
I just started learning Haskell about filtering lists.
Suppose I have the following list : [2, 3, 4, 5, 8, 10, 11]
I would like to keep only those numbers in the list, which are not divisible by the other members.
The result of our example would be : [2, 3, 5, 11]
[x | x <- src, all (\y -> x `rem` y /= 0) (filter (<x) src)]
where src = [2,3,4,5,8,10,11]
It should be noted that you actually also mean dividable by other numbers that are below it, and not just any number in that list, which is why there's a filter in the 2nd argument for all.
The result, of course, is the one you expect in your question: [2,3,5,11].
Here's how it works (and if I'm missing anything, let me know and I'll update).
I'll explain the code side-by-side with normal English. I suggest you just read just the English first, and afterwards see how each statement is expressed in code - I think it should be the most friendly for a newcomer.
Also note that I flipped the arguments for filter and all below (it is invalid!) to make the explanation fluid.
[x|: Construct a list made out of x
x <- src: Where x is an element from src
,: But only the elements that satisfy the following predicate/rule:
all of the numbers from
(filter src (<x)): src that are lesser-than the current x
(\y -> x 'rem' y /= 0): must not yield a remainder equal to 0.
]
For the code part to make sense, make sure you've familiarized yourself with all, filter, rem, and the syntax for: list comprehensions, lambda expressions, sections, and backticks.
On GHC,
Prelude> :m + Data.List
Prelude Data.List> nubBy (\a b -> rem a b == 0) [2,3,4,5,8,10,11]
[2,3,5,11]
does the trick. On Haskell98-compatible systems (e.g. Hugs), use nubBy (\b a -> rem a b == 0).
This answer was posted as a comment by Will Ness.
Using filter
filter :: (a -> Bool) -> [a] -> [a]
and from Data.Numbers.Primes the function
isPrime :: Integral int => int -> Bool
may be
filter isPrime [2, 3, 4, 5, 8, 10, 11]
or using list comprehension
[ x | x <- [2, 3, 4, 5, 8, 10, 11], isPrime x]
change filter predicate as you wish, e.g.
-- None `xs` element (different than `x`) divide `x`
noneDiv xs x = and [x `mod` y /= 0 | y <- xs, x /= y]
now
myFilter xs = filter (noneDiv xs) xs
or
myFilter xs = [x | x <- xs, noneDiv xs x]
Create an infinite list pairs :: [(Integer, Integer)] containing pairs of the form (m,n),
where each of m and n is a member of [0 ..]. An additional requirement is that if (m,n)
is a legit member of the list, then (elem (m,n) pairs) should return True in finite time.
An implementation of pairs that violates this requirement is considered a non- solution.
****Fresh edit Thank you for the comments, Lets see if I can make some progress****
pairs :: [(Integer, Integer)]
pairs = [(m,n) | t <- [0..], m <- [0..], n <-[0..], m+n == t]
Something like this? I just don't know where it's going to return True in finite time.
I feel the way the question is worded elem doesn't have to be part of my answer. Just if you call (elem (m,n) pairs) it should return true. Sound right?
Ignoring the helper method, the list comprehension you have will list out all pairs but the order of elements is a problem. You'll have a infinitely many pairs like (0, m) which are followed by infinitely many pairs like (1, m). Of course elem will forever iterate all the (0, m) pairs never reaching (1, m) or (2, m) etc.
I'm not sure why you have the helper method -- with it, you are only building a list of pairs like [(0,0), (1,1), (2,2), ...] because you've filtered on m = n. Was that part of the requirements?
Like #hammar suggested, start with 0 = m + n and list out the pairs (m, n). Then list pairs (m, n) where 1 = m + n. Then your list will look like [(0,0), (0,1), (1,0), (0,2), (1,1), (2,0), ...].
The helper function ensures that pairs is a list of the form [ (0,0) , (1,1) , (2,2) ... ].
So elem ( m , n ) pairs can be implemented as:
elem (m , n) _ | m == n = True
| otherwise = False
This is a constant time implementation.
I first posted
Prelude> let pairs = [(m, n) | t <- [0..]
, let m = head $ take 1 $ drop t [0..]
, let n = head $ take 1 $ drop (t + 1) [0..]]
Which, I believed answered the three conditions set by the professor. But hammar pointed out that if I chose this list as an answer, that is, the list of pairs of the form (t, t+1), then I might as well choose the list
repeat [(0,0)]
Well, both of these do seem to answer the professor's question, considering there seems to be no mention of the list having to contain all combinations of [0..] and [0..].
That aside, hammer helped me see how you can list all combinations, facilitating the evaluation of elem in finite time by building the infinite list from finite lists. Here are two other finite lists - less succinct than Hammar's suggestion of the diagonals - that seem to build all combinations of [0..] and [0..]:
edges = concat [concat [[(m,n),(n,m)] | let m = t, n <- take m [0..]] ++ [(t,t)]
| t <- [0..]]
*Main> take 9 edges
[(0,0),(1,0),(0,1),(1,1),(2,0),(0,2),(2,1),(1,2),(2,2)]
which construct the edges (t, 0..t) (0..t, t), and
oddSpirals size = concat [spiral m size' | m <- n] where
size' = if size < 3 then 3 else if even size then size - 1 else size
n = map (\y -> (fst y * size' + div size' 2, snd y * size' + div size' 2))
[(x, t-x) | let size' = 5, t <- [0..], x <- [0..t]]
spiral seed size = spiral' (size - 1) "-" 1 [seed]
spiral' limit op count result
| count == limit =
let op' = if op == "-" then (-) else (+)
m = foldl (\a b -> a ++ [(op' (fst $ last a) b, snd $ last a)]) result (replicate count 1)
nextOp = if op == "-" then "+" else "-"
nextOp' = if op == "-" then (+) else (-)
n = foldl (\a b -> a ++ [(fst $ last a, nextOp' (snd $ last a) b)]) m (replicate count 1)
n' = foldl (\a b -> a ++ [(nextOp' (fst $ last a) b, snd $ last a)]) n (replicate count 1)
in n'
| otherwise =
let op' = if op == "-" then (-) else (+)
m = foldl (\a b -> a ++ [(op' (fst $ last a) b, snd $ last a)]) result (replicate count 1)
nextOp = if op == "-" then "+" else "-"
nextOp' = if op == "-" then (+) else (-)
n = foldl (\a b -> a ++ [(fst $ last a, nextOp' (snd $ last a) b)]) m (replicate count 1)
in spiral' limit nextOp (count + 1) n
*Main> take 9 $ oddSpirals 3
[(1,1),(0,1),(0,2),(1,2),(2,2),(2,1),(2,0),(1,0),(0,0)]
which build clockwise spirals of length 'size' squared, superimposed on hammar's diagonals algorithm.
I believe the solution to your task is:
pairs = [(x,y) | u <- [0..], x <- [0..u], y <-[0..u] , u == x+y]
I've just started learning about Functional Programming, using Haskel.
I'm slowly getting through Erik Meijer's lectures on Channel 9 (I've watched the first 4 so far) and in the 4th video Erik explains how tail works, and it fascinated me.
I've tried to write a function that returns the middle of a list (2 items for even lengths, 1 for odd) and I'd like to hear how others would implement it in
The least amount of Haskell code
The fastest Haskell code
If you could explain your choices I'd be very grateful.
My beginners code looks like this:
middle as | length as > 2 = middle (drop 2 (reverse as))
| otherwise = as
Just for your amusement, a solution from someone who doesn't speak Haskell:
Write a recursive function that takes two arguments, a1 and a2, and pass your list in as both of them. At each recursion, drop 2 from a2 and 1 from a1. If you're out of elements for a2, you'll be at the middle of a1. You can handle the case of just 1 element remaining in a2 to answer whether you need 1 or 2 elements for your "middle".
I don't make any performance claims, though it only processes the elements of the list once (my assumption is that computing length t is an O(N) operation, so I avoid it), but here's my solution:
mid [] = [] -- Base case: the list is empty ==> no midpt
mid t = m t t -- The 1st t is the slow ptr, the 2nd is fast
where m (x:_) [_] = [x] -- Base case: list tracked by the fast ptr has
-- exactly one item left ==> the first item
-- pointed to by the slow ptr is the midpt.
m (x:y:_) [_,_] = [x,y] -- Base case: list tracked by the fast ptr has
-- exactly two items left ==> the first two
-- items pointed to by the slow ptr are the
-- midpts
m (_:t) (_:_:u) = m t u -- Recursive step: advance slow ptr by 1, and
-- advance fast ptr by 2.
The idea is to have two "pointers" into the list, one that increments one step at each point in the recursion, and one that increments by two.
(which is essentially what Carl Smotricz suggested)
Two versions
Using pattern matching, tail and init:
middle :: [a] -> [a]
middle l#(_:_:_:_) = middle $ tail $ init l
middle l = l
Using length, take, signum, mod, drop and div:
middle :: [a] -> [a]
middle xs = take (signum ((l + 1) `mod` 2) + 1) $ drop ((l - 1) `div ` 2) xs
where l = length xs
The second one is basically a one-liner (but uses where for readability).
I've tried to write a function that returns the middle of a list (2 items for even lengths, 1 for odd) and I'd like to hear how others would implement it in
The right datastructure for the right problem. In this case, you've specified something that only makes sense on a finite list, right? There is no 'middle' to an infinite list. So just reading the description, we know that the default Haskell list may not be the best solution: we may be paying the price for the laziness even when we don't need it. Notice how many of the solutions have difficulty avoiding 2*O(n) or O(n). Singly-linked lazy lists just don't match a quasi-array-problem too well.
Fortunately, we do have a finite list in Haskell: it's called Data.Sequence.
Let's tackle it the most obvious way: 'index (length / 2)'.
Data.Seq.length is O(1) according to the docs. Data.Seq.index is O(log(min(i,n-i))) (where I think i=index, and n=length). Let's just call it O(log n). Pretty good!
And note that even if we don't start out with a Seq and have to convert a [a] into a Seq, we may still win. Data.Seq.fromList is O(n). So if our rival was a O(n)+O(n) solution like xs !! (length xs), a solution like
middle x = let x' = Seq.fromList x in Seq.index(Seq.length x' `div` 2)
will be better since it would be O(1) + O(log n) + O(n), which simplifies to O(log n) + O(n), obviously better than O(n)+O(n).
(I leave as an exercise to the reader modifying middle to return 2 items if length be even and 1 if length be odd. And no doubt one could do better with an array with constant-time length and indexing operations, but an array isn't a list, I feel.)
Haskell solution inspired by Carl's answer.
middle = m =<< drop 1
where m [] = take 1
m [_] = take 2
m (_:_:ys) = m ys . drop 1
If the sequence is a linked list, traversal of this list is the dominating factor of efficiency. Since we need to know the overall length, we have to traverse the list at least once. There are two equivalent ways to get the middle elements:
Traverse the list once to get the length, then traverse it half to get at the middle elements.
Traverse the list in double steps and single steps at the same time, so that when the first traversal stops, the second traversal is in the middle.
Both need the same number of steps. The second is needlessly complicated, in my opinion.
In Haskell, it might be something like this:
middle xs = take (2 - r) $ drop ((div l 2) + r - 1) xs
where l = length xs
r = rem l 2
middle xs =
let (ms, len) = go xs 0 [] len
in ms
go (x:xs) i acc len =
let acc_ = case len `divMod` 2 of
(m, 0) -> if m == (i+1) then (take 2 (x:xs))
else acc
(m, 1) -> if m == i then [x]
else acc
in go xs (i+1) acc_ len
go [] i acc _ = (acc,i)
This solution traverses the list just once using lazy evaluation. While it traverses the list, it calculates the length and then backfeeds it to the function:
let (ms, len) = go xs 0 [] len
Now the middle elements can be calculated:
let acc' = case len `divMod` 2 of
...
F# solution based on Carl's answer:
let halve_list l =
let rec loop acc1 = function
| x::xs, [] -> List.rev acc1, x::xs
| x::xs, [y] -> List.rev (x::acc1), xs
| x::xs, y::y'::ys -> loop (x::acc1) (xs, ys)
| [], _ -> [], []
loop [] (l, l)
It's pretty easy to modify to get the median elements in the list too:
let median l =
let rec loop acc1 = function
| x::xs, [] -> [List.head acc1; x]
| x::xs, [y] -> [x]
| x::xs, y::y'::ys -> loop (x::acc1) (xs, ys)
| [], _ -> []
loop [] (l, l)
A more intuitive approach uses a counter:
let halve_list2 l =
let rec loop acc = function
| (_, []) -> [], []
| (0, rest) -> List.rev acc, rest
| (n, x::xs) -> loop (x::acc) (n - 1, xs)
let count = (List.length l) / 2
loop [] (count, l)
And a really ugly modification to get the median elements:
let median2 l =
let rec loop acc = function
| (n, [], isEven) -> []
| (0, rest, isEven) ->
match rest, isEven with
| x::xs, true -> [List.head acc; x]
| x::xs, false -> [x]
| _, _ -> failwith "Should never happen"
| (n, x::xs, isEven) -> loop (x::acc) (n - 1, xs, isEven)
let len = List.length l
let count = len / 2
let isEven = if len % 2 = 0 then true else false
loop [] (count, l, isEven)
Getting the length of a list requires traversing its entire contents at least once. Fortunately, it's perfectly easy to write your own list data structure which holds the length of the list in each node, allowing you get get the length in O(1).
Weird that this perfectly obvious formulation hasn't come up yet:
middle [] = []
middle [x] = [x]
middle [x,y] = [x,y]
middle xs = middle $ init $ tail xs
A very straightforward, yet unelegant and not so terse solution might be:
middle :: [a] -> Maybe [a]
middle xs
| len <= 2 = Nothing
| even len = Just $ take 2 . drop (half - 1) $ xs
| odd len = Just $ take 1 . drop (half) $ xs
where
len = length xs
half = len `div` 2
This iterates twice over the list.
mid xs = m where
l = length xs
m | l `elem` [0..2] = xs
m | odd l = drop (l `div` 2) $ take 1 $ xs
m | otherwise = drop (l `div` 2 - 1) $ take 2 $ xs
I live for one liners, although this example only works for odd lists. I just want to stretch my brain! Thank you for the fun =)
foo d = map (\(Just a) -> a) $ filter (/=Nothing) $ zipWith (\a b -> if a == b then Just a else Nothing) (Data.List.nub d) (Data.List.nub $ reverse d)
I'm not much of a haskeller myself but I tried this one.
First the tests (yes, you can do TDD using Haskell)
module Main
where
import Test.HUnit
import Middle
main = do runTestTT tests
tests = TestList [ test1
, test2
, test3
, test4
, test_final1
, test_final2
]
test1 = [0] ~=? middle [0]
test2 = [0, 1] ~=? middle [0, 1]
test3 = [1] ~=? middle [0, 1, 2]
test4 = [1, 2] ~=? middle [0, 1, 2, 3]
test_final1 = [3] ~=? middle [0, 1, 2, 3, 4, 5, 6]
test_final2 = [3, 4] ~=? middle [0, 1, 2, 3, 4, 5, 6, 7]
And the solution I came to:
module Middle
where
middle a = midlen a (length a)
midlen (a:xs) 1 = [a]
midlen (a:b:xs) 2 = [a, b]
midlen (a:xs) lg = midlen xs (lg - (2))
It will traverse list twice, once for getting length and a half more to get the middle, but I don't care it's still O(n) (and getting the middle of something implies to get it's length, so no reason to avoid it).
My solution, I like to keep things simple:
middle [] = []
middle xs | odd (length xs) = [xs !! ((length xs) `div` 2)]
| otherwise = [(xs !! ((length xs) `div` 2)),(reverse $ xs) !! ((length xs)`div` 2)]
Use of !! in Data.List as the function to get the value at a given index, which in this case is half the length of the list.
Edit: it actually works now
I like Svante's answer. My version:
> middle :: [a] -> [a]
> middle [] = []
> middle xs = take (r+1) . drop d $ xs
> where
> (d,r) = (length xs - 1) `divMod` 2
Here is my version. It was just a quick run up. I'm sure it's not very good.
middleList xs#(_:_:_:_) = take (if odd n then 1 else 2) $ drop en xs
where n = length xs
en = if n < 5 then 1 else 2 * (n `div` 4)
middleList xs = xs
I tried. :)
If anyone feels like commenting and telling me how awful or good this solution is, I would deeply appreciate it. I'm not very well versed in Haskell.
EDIT: Improved with suggestions from kmc on #haskell-blah
EDIT 2: Can now accept input lists with a length of less than 5.
Another one-line solution:
--
middle = ap (take . (1 +) . signum . (`mod` 2) . (1 +) . length) $ drop =<< (`div` 2) . subtract 1 . length
--