Related
If I create a infinite list like this:
let t xs = xs ++ [sum(xs)]
let xs = [1,2] : map (t) xs
take 10 xs
I will get this result:
[
[1,2],
[1,2,3],
[1,2,3,6],
[1,2,3,6,12],
[1,2,3,6,12,24],
[1,2,3,6,12,24,48],
[1,2,3,6,12,24,48,96],
[1,2,3,6,12,24,48,96,192],
[1,2,3,6,12,24,48,96,192,384],
[1,2,3,6,12,24,48,96,192,384,768]
]
This is pretty close to what I am trying to do.
This current code uses the last value to define the next. But, instead of a list of lists, I would like to know some way to make an infinite list that uses all the previous values to define the new one.
So the output would be only
[1,2,3,6,12,24,48,96,192,384,768,1536,...]
I have the definition of the first element [1].
I have the rule of getting a new element, sum all the previous elements.
But, I could not put this in the Haskell grammar to create the infinite list.
Using my current code, I could take the list that I need, using the command:
xs !! 10
> [1,2,3,6,12,24,48,96,192,384,768,1536]
But, it seems to me, that it is possible doing this in some more efficient way.
Some Notes
I understand that, for this particular example, that was intentionally oversimplified, we could create a function that uses only the last value to define the next.
But, I am searching if it is possible to read all the previous values into an infinite list definition.
I am sorry if the example that I used created some confusion.
Here another example, that is not possible to fix using reading only the last value:
isMultipleByList :: Integer -> [Integer] -> Bool
isMultipleByList _ [] = False
isMultipleByList v (x:xs) = if (mod v x == 0)
then True
else (isMultipleByList v xs)
nextNotMultipleLoop :: Integer -> Integer -> [Integer] -> Integer
nextNotMultipleLoop step v xs = if not (isMultipleByList v xs)
then v
else nextNotMultipleLoop step (v + step) xs
nextNotMultiple :: [Integer] -> Integer
nextNotMultiple xs = if xs == [2]
then nextNotMultipleLoop 1 (maximum xs) xs
else nextNotMultipleLoop 2 (maximum xs) xs
addNextNotMultiple xs = xs ++ [nextNotMultiple xs]
infinitePrimeList = [2] : map (addNextNotMultiple) infinitePrimeList
take 10 infinitePrimeList
[
[2,3],
[2,3,5],
[2,3,5,7],
[2,3,5,7,11],
[2,3,5,7,11,13],
[2,3,5,7,11,13,17],
[2,3,5,7,11,13,17,19],
[2,3,5,7,11,13,17,19,23],
[2,3,5,7,11,13,17,19,23,29],
[2,3,5,7,11,13,17,19,23,29,31]
]
infinitePrimeList !! 10
[2,3,5,7,11,13,17,19,23,29,31,37]
You can think so:
You want to create a list (call them a) which starts on [1,2]:
a = [1,2] ++ ???
... and have this property: each next element in a is a sum of all previous elements in a. So you can write
scanl1 (+) a
and get a new list, in which any element with index n is sum of n first elements of list a. So, it is [1, 3, 6 ...]. All you need is take all elements without first:
tail (scanl1 (+) a)
So, you can define a as:
a = [1,2] ++ tail (scanl1 (+) a)
This way of thought you can apply with other similar problems of definition list through its elements.
If we already had the final result, calculating the list of previous elements for a given element would be easy, a simple application of the inits function.
Let's assume we already have the final result xs, and use it to compute xs itself:
import Data.List (inits)
main :: IO ()
main = do
let is = drop 2 $ inits xs
xs = 1 : 2 : map sum is
print $ take 10 xs
This produces the list
[1,2,3,6,12,24,48,96,192,384]
(Note: this is less efficient than SergeyKuz1001's solution, because the sum is re-calculated each time.)
unfoldr has a quite nice flexibility to adapt to various "create-a-list-from-initial-conditions"-problems so I think it is worth mentioning.
A little less elegant for this specific case, but shows how unfoldr can be used.
import Data.List
nextVal as = Just (s,as++[s])
where s = sum as
initList = [1,2]
myList =initList ++ ( unfoldr nextVal initList)
main = putStrLn . show . (take 12) $ myList
Yielding
[1,2,3,6,12,24,48,96,192,384,768,1536]
in the end.
As pointed out in the comment, one should think a little when using unfoldr. The way I've written it above, the code mimicks the code in the original question. However, this means that the accumulator is updated with as++[s], thus constructing a new list at every iteration. A quick run at https://repl.it/languages/haskell suggests it becomes quite memory intensive and slow. (4.5 seconds to access the 2000nd element in myList
Simply swapping the acumulator update to a:as produced a 7-fold speed increase. Since the same list can be reused as accumulator in every step it goes faster. However, the accumulator list is now in reverse, so one needs to think a little bit. In the case of predicate function sum this makes no differece, but if the order of the list matters, one must think a little bit extra.
You could define it like this:
xs = 1:2:iterate (*2) 3
For example:
Prelude> take 12 xs
[1,2,3,6,12,24,48,96,192,384,768,1536]
So here's my take. I tried not to create O(n) extra lists.
explode ∷ Integral i ⇒ (i ->[a] -> a) -> [a] -> [a]
explode fn init = as where
as = init ++ [fn i as | i <- [l, l+1..]]
l = genericLength init
This convenience function does create additional lists (by take). Hopefully they can be optimised away by the compiler.
explode' f = explode (\x as -> f $ take x as)
Usage examples:
myList = explode' sum [1,2]
sum' 0 xs = 0
sum' n (x:xs) = x + sum' (n-1) xs
myList2 = explode sum' [1,2]
In my tests there's little performance difference between the two functions. explode' is often slightly better.
The solution from #LudvigH is very nice and clear. But, it was not faster.
I am still working on the benchmark to compare the other options.
For now, this is the best solution that I could find:
-------------------------------------------------------------------------------------
-- # infinite sum of the previous using fuse
-------------------------------------------------------------------------------------
recursiveSum xs = [nextValue] ++ (recursiveSum (nextList)) where
nextValue = sum(xs)
nextList = xs ++ [nextValue]
initialSumValues = [1]
infiniteSumFuse = initialSumValues ++ recursiveSum initialSumValues
-------------------------------------------------------------------------------------
-- # infinite prime list using fuse
-------------------------------------------------------------------------------------
-- calculate the current value based in the current list
-- call the same function with the new combined value
recursivePrimeList xs = [nextValue] ++ (recursivePrimeList (nextList)) where
nextValue = nextNonMultiple(xs)
nextList = xs ++ [nextValue]
initialPrimes = [2]
infiniteFusePrimeList = initialPrimes ++ recursivePrimeList initialPrimes
This approach is fast and makes good use of many cores.
Maybe there is some faster solution, but I decided to post this to share my current progress on this subject so far.
In general, define
xs = x1 : zipWith f xs (inits xs)
Then it's xs == x1 : f x1 [] : f x2 [x1] : f x3 [x1, x2] : ...., and so on.
Here's one example of using inits in the context of computing the infinite list of primes, which pairs them up as
ps = 2 : f p1 [p1] : f p2 [p1,p2] : f p3 [p1,p2,p3] : ...
(in the definition of primes5 there).
I'm trying to implement the Newton-Raphson method on Haskell, and so far I have managed to get it working by using the iterate function, but the problem is that it retuns an infinte list due the nature of the iterate function, so I'm looking to find a way of stopping the loop when the value obtained in an iteration falls into a set margin of error, and returning said value
I looked some blog posts and even some questions on here, but I'm fairly new to haskell and not fully versed on the syntaxis, so for me reading code exmples or documentation is really hard by now.
Definitions of f(x) and g(x) (the derivative) are irelevant:
newton x0 = iterate step x0
where step xn = xn - ((f xn)/(g xn))
I'm currently working by taking the first elements of the list given, using take 4 $ newton 3.5 in the GHCi prompt, but the list returned by iterate is infinite, so I cannot use a tail function on it.
My idea is to set a constant somewhere, margin = 0.0001 or something like that, and when the last iteration of the newton function falls behind the margin, the iterate function stops, and I have the final result
A variation of duplode's answer that only uses standard functions:
newton :: Double -> Double
newton x0 = (snd . head . dropWhile (not . goal)) (zip approxs (tail approxs))
where
approxs = iterate step x0
step xn = xn - (f xn / g xn)
goal (xa, xb) = abs (xb - xa) < margin
To determine whether our goal has been reached, we need to examine adjacent pairs of elements of the infinite list produced by iterate. To do that, we use the standard trick of zipping up the list with its own tail. (If you're feeling extra cheeky, consider using (zip <*> tail) approxs instead of zip approxs (tail approxs). That way you don't have to mention approxs twice in the expression, which is admittedly a bit pointless.)
This gives us an infinite list of pairs, from which we drop elements until the difference between components of a pair gets small enough. At that point we extract the head of the remaining list (a pair) and take the second component.
You want to test pairs of consecutive values generated by newton. That means dropWhile from the Prelude won't be quite enough, as it only tests individual elements. Instead, you can use something like this dropWhileList from MissingH:
newton :: Double -> Double
newton x0 = dropWhileList (not . goal) (iterate step x0) !! 1
where
step xn = xn - ((f xn)/(g xn))
goal (xa:xb:_) = abs (xb - xa) < margin
goal _ = False
!! 1 give you the second element of the list. While it is a partial function (it fails if the list doesn't have a second element), here it is safe to use (as iterate generates an infinite list, you will have a result as long as the Newton's method converges).
Picking up oisdk's suggestion of using until...
until :: (a -> Bool) -> (a -> a) -> a -> a
... for an implementation that doesn't literally generate a list:
newton :: Double -> Double
newton = snd . until goal (move . snd) . move
where
step xn = xn - (f xn)/(g xn)
move xn = (xn, step xn) -- The cheeky spelling is (,) <*> step
goal (xa,xb) = abs (xb - xa) < margin
It is worth it comparing this with melpomene's zip-based implementation and noting the parallels.
Currently I am using
takeWhile (\x -> x /= 1 && x /= 89) l
to get the elements from a list up to either a 1 or 89. However, the result doesn't include these sentinel values. Does Haskell have a standard function that provides this variation on takeWhile that includes the sentinel in the result? My searches with Hoogle have been unfruitful so far.
Since you were asking about standard functions, no. But also there isn't a package containing a takeWhileInclusive, but that's really simple:
takeWhileInclusive :: (a -> Bool) -> [a] -> [a]
takeWhileInclusive _ [] = []
takeWhileInclusive p (x:xs) = x : if p x then takeWhileInclusive p xs
else []
The only thing you need to do is to take the value regardless whether the predicate returns True and only use the predicate as a continuation factor:
*Main> takeWhileInclusive (\x -> x /= 20) [10..]
[10,11,12,13,14,15,16,17,18,19,20]
Is span what you want?
matching, rest = span (\x -> x /= 1 && x /= 89) l
then look at the head of rest.
The shortest way I found to achieve that is using span and adding a function before it that takes the result of span and merges the first element of the resulting tuple with the head of the second element of the resulting tuple.
The whole expression would look something like this:
(\(f,s) -> f ++ [head s]) $ span (\x -> x /= 1 && x /= 89) [82..140]
The result of this expression is
[82,83,84,85,86,87,88,89]
The first element of the tuple returned by span is the list that takeWhile would return for those parameters, and the second element is the list with the remaining values, so we just add the head from the second list to our first list.
I am doing project euler question 136, and came up with the following to test the example given:
module Main where
import Data.List
unsum x y z n = (y > 0) && (z > 0) && (((x*x) - (y*y)- (z*z)) == n) && ((x - y) == (y - z))
answer = snub $ takeWhile (<100) [n|x<-[1..],d<-[1..x`div`2],n<-[x..100],y<-[x-d],z<-[y-d], unsum x y z n ]
where
snub [] = []
snub (x:xs) | elem x xs = snub (filter (/=x) xs)
| otherwise = x : snub xs
snub will remove any numbers that are duplicates from a list.
The example is supposed to give 25 solutions for n where x^2 - y^2 - z^2 == n and all numbers are positive (or so I gather from the question) and are an arithmetic progression such that x-y == y-z. But when I use the code, a list of 11 solutions for n are returned.
What have I done wrong in my list comprehension and are there any optimisations I have missed out?
point 1
I made an attempt at this question and found that this was the sequence of ns that I came up with
[4,3,16,12,7,20,11,48,28,19,80,44,23,52,112,31,68,76,1156,43,176,559...
which potentially means that your takeWhile (<100) is the wrong filtering function to use to determine when to stop. On a related note, I tried running this:
answer = snub $ filter (<=100) $ takeWhile (<200) [...listcomprehension...]
But i gave up because it was taking too long. Which leads me to point 2.
point 2
In terms of optimisations, look at what your list comprehension produces in terms of raw output.
Main> take 30 [(x,y,z,n) | x<-[1..], d<-[1..x`div`2], n<-[x..100], y<-[x-d], z<-[y-d]]
[(2,1,0,2),(2,1,0,3),(2,1,0,4),(2,1,0,5),(2,1,0,6),(2,1,0,7),(2,1,0,8),(2,1,0,9),
(2,1,0,10),(2,1,0,11),(2,1,0,12),(2,1,0,13),(2,1,0,14),(2,1,0,15),(2,1,0,16),(2,1,0,17),
(2,1,0,18),(2,1,0,19),(2,1,0,20),(2,1,0,21),(2,1,0,22),(2,1,0,23),(2,1,0,24),(2,1,0,25),
(2,1,0,26),(2,1,0,27),(2,1,0,28),(2,1,0,29),(2,1,0,30),(2,1,0,31)]
This means that unsum is being called on each combination of x y z and n, which is a little bit redundant since we know that 2^2 - 1^2 - 0^2 = 3.
It is also much simpler and much less redundant to move the calculation of n from the list comprehension (slow because of above) to a function and merely list comprehend the (x,y,z) combinations that are valid.
ns = map nsum [(x, x-d, x-d-d) | x <- [1..], d <- [1..x`div`2]]
nsum (x,y,z) = x^2 - y^2 - z^2
Then it is possible to calculate the answer from this infinite list, but beware of using takewhile.
I was doing the exercises from YAHT's Recursive Datatype section, and found writing the listFoldr function a bit challenging (mainly because I didn't really understand the difference between foldl and foldr at first). When I finally realized exactly how the foldr function worked, I decided that a simple swap of function arguments would be all that'd be needed to change my listFoldl function to a listFoldr function:
listFoldl f i [] = i
listFoldl f i (x:xs) = listFoldl f (f i x) xs
listFoldr f i [] = i
listFoldr f i (x:xs) = listFoldr f (f x i) xs
This appears to work (I did more tests than this):
Main> foldr (-) 4 [1, 2, 3]
-2
Main> listFoldr (-) 4 [1, 2, 3]
-2
But the solution given for the exercise is much different than mine. Their listFoldl is exactly the same as mine, but look at their listFoldr:
listFoldr f i [] = i
listFoldr f i (x:xs) = f x (listFoldr f i xs)
Which solution is better, mine or theirs? Is one of them incorrect? (In my tests, they both end up with the exact same result...)
Your solution is definitely incorrect. You have simply implemented a foldl in which the function f takes arguments in the opposite order. For example of what is wrong, foldr (:) [] is supposed to be an identify function on lists, but your function reverses the list. There are lots of other reasons why your function is not foldr, like how foldr works on infinite lists and yours does not. It is a pure coincidence that they are the same in your example, because 3 - (2 - (1 - 4)) == 1 - (2 - (3 - 4)). I think you should start from scratch and look at how foldr is supposed to work.
I think you are processing the elements in the 'opposite order', and so yours is not right.
You should be able to demonstrate this with an example where 'order matters'. For example, something like
listfoldr f "" ["a", "b", "c"]
where 'f' is a function along the lines of
f s1 s2 = "now processing f(" # s1 # "," # s2 # ")\n"
where '#' is a string-append operator (I forget what it is in Haskell). The point is just to 'instrument' the function so you can see what order it is getting called with the various args.
(Note that this didn't show up in your example because the math "4-1-2-3" yields the same answer as "4-3-2-1".)
Yours is broken. Try it with something that doesn't end up with a single numeric result.
eg: listFoldr (++) "a" ["b", "c", "d"]
You're processing in the wrong direction.
On a list [x1, x2, ..., xk], your listFoldr computes
f xk (... (f x2 (f x1 i)) ...)
whereas foldr should compute
f x1 (f x2 (... (f xk i) ...))
(In comparison, foldl computes
f (... (f (f i x1) x2) ...) xk
Essentially, listFoldr f = foldl (flip f).)
You're test case is unfortunate, because
3 - (2 - (1 - 4)) = 1 - (2 - (3 - 4))
When you are testing functions like these, be sure to pass in an f that is non-commutative and non-associative (i.e., argument and application order matter), so you can be sure the expression is evaluated correctly. Of course, subtraction is non-commutative and non-associative and you just got unlucky.