How can I effectively represent the list [0..] \\ [t+0*p, t+1*p ..] ?
[0..] \\ [t+0*p, t+1*p ..]
I defined:
Prelude> let factors pt = [t+0*p, t+1*p ..]
I want to efficiently present an infinite list, which is the difference [0..] and factors pt , but using \\ from Data.List requires too much memory for even medium lists:
[0..]
factors pt
\\
Data.List
Prelude Data.List> [0..10000] \\ (factors 5 0) <interactive>: out of memory
I know that I can represent the values between t+0*p and t+1*p with:
t+0*p
t+1*p
Prelude> let innerList p1 p2 t = [t+p1+1, t+p1+2 .. t+p2-1] Prelude> innerList 0 5 0 [1,2,3,4]
However, recalculating and concatenating the innerList to increase the intervals seems clumsy.
innerList
Can I effectively represent [0..] \\ (factors pt) without calculating rem or mod for each element?
[0..] \\ (factors pt)
rem
mod
For an infinite list [0..] \\ [t,t+p..] ,
[0..] \\ [t,t+p..]
yourlist tp = [0..t-1] ++ [i | m <- [0,p..], i <- [t+m+1..t+m+p-1]]
Of course, this approach does not scale at all if you want to remove some other factors, for example
[0..] \\ [t,t+p..] \\ [s,s+q..] \\ ...
in this case you will have to delete them in the sequence with minus mentioned in Daniel Fisher's answer. There is no magic bullet.
minus
But there is also a union , with which it will be higher
union
[0..] \\ ( [t,t+p..] `union` [s,s+q..] `union` ... )
the advantage is that you organize unions in a tree and achieve algorithmic improvement.
You cannot use (\\) for this, because
(\\)
(\\) :: (Eq a) => [a] -> [a] -> [a] (\\) = foldl (flip delete)
the list of items you want to delete is endless, and the left fold never ends when the list it adds is endless.
If you prefer to use something already written than to write it yourself, you can use minus from data-ordlist .
Efficiency must be adequate.
Otherwise,
minus :: Ord a => [a] -> [a] -> [a] minus xxs@ (x:xs) yys@ (y:ys) | x < y = x : minus xs yys | x == y = minus xs ys | otherwise = minus xss ys minus xs _ = xs
You can use compiling a list with a predicate using rem :
>>> let t = 0 >>> let p = 5 >>> take 40 $ [ x | x <- [1..], x `rem` p /= t ] [1,2,3,4,6,7,8,9,11,12,13,14,16,17,18,19,21,22,23,24,26,27,28,29,31,32,33,34,36,37,38,39,41,42,43,44,46,47,48,49]
If you need efficiency, why should your solution use list comprehension syntax?
Why not something like this?
gen' nip | i == p = gen' (n + p) 1 p gen' nip = (n+i) : gen' n (i+1) p gen = gen' 0 1
and then do
gen 5
Since you have bottom-up lists, you can simply lazily combine them:
nums = [1..] nogos = factors pt result = merge nums (dropWhile (<head nums) nogos) where merge (a:as) (b:bs) | a < b = a : merge as (b:bs) | a == b = merge as bs | otherwise = error "should not happen"
Writing this in a general way so that we have a function that builds the difference of two infinite lists, provided that they are in ascending order, remains as an exercise. As a result, the following should be possible:
[1..] `infiniteDifference` primes `infiniteDifference` squares
To do this, make it the left associative operator.
Source: https://habr.com/ru/post/1497860/More articles:A synthetic blend of SSE and AVX - c ++SVG for PNG in javascript with filter support - javascriptdll is not copied to the output directory, even with the Copy Local flag ( true ) - dllUsing FBEvents activateApp on iOS, and phone markup is not published on Facebook Insights - apiHttpClient should be redirected - javaPython code to trigger a keystroke? - pythonDestroy general list in Gson - javaGit Bash on windows 7 behind proxy server no longer works - gitEvent handler to switch from other applications to Excel? - vbaDropdown position of bootstrap fixed with container boundary radius disappearing abroad in IE - cssAll Articles