{-# OPTIONS_GHC -O2 #-}
module Main where
import Data.Array.Unboxed
main = do
print {- $ fork(last,length) -} $ primesToAO
(read m
)
-- the simplest Sieve of Eratosthenes formulation, using
-- an array that is passed as an accumulating argument
-- between steps of iterative computation, and as such
-- (could be, but ain't) liable to the destructive update (but is fast, still,
-- on unboxed arrays, with explicit type signature)
primesToA m
| m
> 2 = sieve
3 (array
(3,m
) [(i
,odd i
) | i
<-[3..m
]] -- 16M:2.03s -- (zip [3..m] $ cycle [True,False]) -- 16M:2.90s
where
sieve p a
| p*p > m = 2 : [i | (i,True) <- assocs a]
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]
fork (f,g) x = (f x,g x) -- f &&& g
-- apply the simple optimization of working with odds only: --------
primesToAO m | m > 2 = sieve 3 (-- array (1,m1) [(i,True) | i<-[1..m1]] -- 16M 0.73s-7.8MB
accumArray
const True
(1,m1
) [] -- 16M 0.68s-7.8MB where
sieve p a
| p > r = let
last = head [i
| i
<-[u
,u
-1..l
], a
!i
] -- plug len
= length [() | (i
,True
) <- assocs a
] -- the leak (l,u) = bounds a
in (last*2+1, len
+1) -- '2' is prime too | a!p1 = sieve (p+2) $ a//[(i,False) | i <- [q1, q1+p..m1]]
{-
en.wikipedia.org/wiki/Prime_number_theorem#Approximations_for_the_nth_prime_number
n(log n + log(log n) - 1) < p_n < n(log n + log(log n)) , for n >= 6
aaprimes n =
let x=fromIntegral n
a=primesToA $ ceiling $ x*(log x + log(log x)) -- good for n >= 4 (p >= 7)
(l,u)=bounds a
p=head [i | i<-[u,u-1..l], a!i]
len=length [() | (i,True) <- assocs a]
..........
m n Data.Array Data.Array.Unboxed Odds_Only
Theoretical
100k (99991,9592) 0.13s-6.8MB 0.02s-4.8MB cpxty
200k (199999,17984) 0.39s-9.9MB n^1.75 0.03s-4.8MB n*log n*log(log n)
400k (399989,33860) 1.06s-26.3MB n^1.58 0.04s-4.8MB
1M (999983,78498) 3.99s-45.7MB n^1.58 0.09s-5.8MB 0.04s-4.8MB
2M (1999993,148933) 11.46s-84.6 n^1.65 0.16s-7.8MB n^0.90-1.72 n^1.122 0.07s-4.8MB
4M (3999971,283146) 0.34s-9.9MB n^1.17-0.83 n^1.114 0.14s-5.8MB n^1.08
8M (7999993,539777) 0.73s-18.1MB n^1.18-1.49 n^1.108 0.31s-5.8MB n^1.23
16M (15999989,1031130) 2.03s-27.3MB n^1.58-0.81 0.68s-7.8MB n^1.21
32M (31999939,1973815) 4.89s-84.6MB n^1.35-1.95 2.13s-11.9MB n^1.76-1.33
50M (49999991,3001134) 8.45s-115.3MB n^1.31-0.78 3.81s-16.0MB n^1.39-1.09
64M (63999979,3785086) 5.24s-20.1MB n^1.37-1.34
100M (99999989,5761455) 9.27s-28.3MB n^1.36-1.02
104M (104395301,6000000) 9.80s-39.6MB -}
ey0jIE9QVElPTlNfR0hDIC1PMiAjLX0KCm1vZHVsZSBNYWluIHdoZXJlCgppbXBvcnQgRGF0YS5BcnJheS5VbmJveGVkCgptYWluID0gZG8KICBtIDwtIGdldExpbmUKICBwcmludCB7LSAkIGZvcmsobGFzdCxsZW5ndGgpIC19ICQgcHJpbWVzVG9BTyAocmVhZCBtKQoKLS0gdGhlIHNpbXBsZXN0IFNpZXZlIG9mIEVyYXRvc3RoZW5lcyBmb3JtdWxhdGlvbiwgdXNpbmcKLS0gYW4gYXJyYXkgdGhhdCBpcyBwYXNzZWQgYXMgYW4gYWNjdW11bGF0aW5nIGFyZ3VtZW50Ci0tIGJldHdlZW4gc3RlcHMgb2YgaXRlcmF0aXZlIGNvbXB1dGF0aW9uLCBhbmQgYXMgc3VjaAotLSAoY291bGQgYmUsIGJ1dCBhaW4ndCkgbGlhYmxlIHRvIHRoZSBkZXN0cnVjdGl2ZSB1cGRhdGUgKGJ1dCBpcyBmYXN0LCBzdGlsbCwgCi0tIG9uIHVuYm94ZWQgYXJyYXlzLCB3aXRoIGV4cGxpY2l0IHR5cGUgc2lnbmF0dXJlKQoKcHJpbWVzVG9BIDo6IEludCAtPiBbSW50XQpwcmltZXNUb0EgbSB8IG0gPiAyID0gc2lldmUgMyAoYXJyYXkgKDMsbSkgIFsoaSxvZGQgaSkgfCBpPC1bMy4ubV1dICAgICAtLSAxNk06Mi4wM3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gKHppcCBbMy4ubV0gJCBjeWNsZSBbVHJ1ZSxGYWxzZV0pICAgICAtLSAxNk06Mi45MHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjogVUFycmF5IEludCBCb29sKQogIHdoZXJlCiAgICBzaWV2ZSBwIGEgCiAgICAgIHwgcCpwID4gbSAgID0gMiA6IFtpIHwgKGksVHJ1ZSkgPC0gYXNzb2NzIGFdCiAgICAgIHwgYSFwICAgICAgID0gc2lldmUgKHArMikgJCBhLy9bKGksRmFsc2UpIHwgaSA8LSBbcCpwLCBwKnArMipwLi5tXV0KICAgICAgfCBvdGhlcndpc2UgPSBzaWV2ZSAocCsyKSBhCgoKZm9yayAoZixnKSB4ID0gKGYgeCxnIHgpICAtLSBmICYmJiBnCgoKLS0gYXBwbHkgdGhlIHNpbXBsZSBvcHRpbWl6YXRpb24gb2Ygd29ya2luZyB3aXRoIG9kZHMgb25seTogLS0tLS0tLS0KCnByaW1lc1RvQU8gOjogSW50IC0+IChJbnQsSW50KQpwcmltZXNUb0FPIG0gfCBtID4gMiA9IHNpZXZlIDMgKC0tIGFycmF5ICgxLG0xKSAgWyhpLFRydWUpIHwgaTwtWzEuLm0xXV0gICAgLS0gMTZNIDAuNzNzLTcuOE1CCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjdW1BcnJheSBjb25zdCBUcnVlICgxLG0xKSBbXSAgICAgICAgICAgICAtLSAxNk0gMC42OHMtNy44TUIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6IFVBcnJheSBJbnQgQm9vbCkKICB3aGVyZQogICAgbTEgPSAobS0xKSBgZGl2YCAyCiAgICByICA9IGZsb29yIC4gc3FydCAkIGZyb21JbnRlZ3JhbCBtICsgMQogICAgc2lldmUgcCBhIAogICAgICB8IHAgPiByICAgICA9IGxldAogICAgICAgICAgICAgICAgICAgICAgbGFzdCA9IGhlYWQgW2kgfCBpPC1bdSx1LTEuLmxdLCBhIWldICAgICAgICAgICAgICAgLS0gcGx1ZwogICAgICAgICAgICAgICAgICAgICAgbGVuICA9IGxlbmd0aCBbKCkgfCAoaSxUcnVlKSA8LSBhc3NvY3MgYV0gICAgICAgICAgIC0tICB0aGUgbGVhawogICAgICAgICAgICAgICAgICAgICAgKGwsdSkgPSBib3VuZHMgYQogICAgICAgICAgICAgICAgICAgIGluICAgKGxhc3QqMisxLCBsZW4rMSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tICcyJyBpcyBwcmltZSB0b28KICAgICAgfCBhIXAxICAgICAgPSBzaWV2ZSAocCsyKSAkIGEvL1soaSxGYWxzZSkgfCBpIDwtIFtxMSwgcTErcC4ubTFdXQogICAgICB8IG90aGVyd2lzZSA9IHNpZXZlIChwKzIpIGEKICAgICAgICAgICAgICAgICAgICAgICB3aGVyZSBwMSA9IChwLTEpIGBkaXZgIDIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxMSA9IChwKnAtMSkgYGRpdmAgMgoKey0KIGVuLndpa2lwZWRpYS5vcmcvd2lraS9QcmltZV9udW1iZXJfdGhlb3JlbSNBcHByb3hpbWF0aW9uc19mb3JfdGhlX250aF9wcmltZV9udW1iZXIKCiBuKGxvZyBuICsgbG9nKGxvZyBuKSAtIDEpIDwgcF9uIDwgIG4obG9nIG4gKyBsb2cobG9nIG4pKSAgLCBmb3IgbiA+PSA2CgphYXByaW1lcyBuID0gCiAgbGV0IHg9ZnJvbUludGVncmFsIG4KICAgICAgYT1wcmltZXNUb0EgJCBjZWlsaW5nICQgeCoobG9nIHggKyBsb2cobG9nIHgpKSAgIC0tIGdvb2QgZm9yIG4gPj0gNCAgKHAgPj0gNykKICAgICAgKGwsdSk9Ym91bmRzIGEKICAgICAgcD1oZWFkIFtpIHwgaTwtW3UsdS0xLi5sXSwgYSFpXQogICAgICBsZW49bGVuZ3RoIFsoKSB8IChpLFRydWUpIDwtIGFzc29jcyBhXQogICAgICAuLi4uLi4uLi4uCgoKICAgICAgICAgbSAgICAgbiAgICAgIERhdGEuQXJyYXkgICAgICAgICAgIERhdGEuQXJyYXkuVW5ib3hlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2Rkc19Pbmx5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGVvcmV0aWNhbAoxMDBrICAoOTk5OTEsOTU5MikgICAgMC4xM3MtNi44TUIgICAgICAgICAgIDAuMDJzLTQuOE1CICAgICAgICAgICAgICAgICAgY3B4dHkKMjAwayAgKDE5OTk5OSwxNzk4NCkgIDAuMzlzLTkuOU1CICAgbl4xLjc1ICAwLjAzcy00LjhNQiAgICAgICAgICAgIG4qbG9nIG4qbG9nKGxvZyBuKQo0MDBrICAoMzk5OTg5LDMzODYwKSAgMS4wNnMtMjYuM01CICBuXjEuNTggIDAuMDRzLTQuOE1CICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCjFNICAgICg5OTk5ODMsNzg0OTgpICAzLjk5cy00NS43TUIgIG5eMS41OCAgMC4wOXMtNS44TUIgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC4wNHMtNC44TUIKMk0gICAgKDE5OTk5OTMsMTQ4OTMzKSAxMS40NnMtODQuNiAgbl4xLjY1ICAwLjE2cy03LjhNQiAgICBuXjAuOTAtMS43MiAgIG5eMS4xMjIgICAwLjA3cy00LjhNQgo0TSAgICAoMzk5OTk3MSwyODMxNDYpICAgICAgICAgICAgICAgICAgICAgIDAuMzRzLTkuOU1CICAgIG5eMS4xNy0wLjgzICAgbl4xLjExNCAgIDAuMTRzLTUuOE1CICAgbl4xLjA4CjhNICAgICg3OTk5OTkzLDUzOTc3NykgICAgICAgICAgICAgICAgICAgICAgMC43M3MtMTguMU1CICAgbl4xLjE4LTEuNDkgICBuXjEuMTA4ICAgMC4zMXMtNS44TUIgICBuXjEuMjMKMTZNICAoMTU5OTk5ODksMTAzMTEzMCkgICAgICAgICAgICAgICAgICAgICAyLjAzcy0yNy4zTUIgICBuXjEuNTgtMC44MSAgICAgICAgICAgICAwLjY4cy03LjhNQiAgIG5eMS4yMQozMk0gICgzMTk5OTkzOSwxOTczODE1KSAgICAgICAgICAgICAgICAgICAgIDQuODlzLTg0LjZNQiAgIG5eMS4zNS0xLjk1ICAgICAgICAgICAgIDIuMTNzLTExLjlNQiAgbl4xLjc2LTEuMzMKNTBNICAoNDk5OTk5OTEsMzAwMTEzNCkgICAgICAgICAgICAgICAgICAgICA4LjQ1cy0xMTUuM01CICBuXjEuMzEtMC43OCAgICAgICAgICAgICAzLjgxcy0xNi4wTUIgIG5eMS4zOS0xLjA5CjY0TSAgKDYzOTk5OTc5LDM3ODUwODYpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNS4yNHMtMjAuMU1CICBuXjEuMzctMS4zNAoxMDBNICg5OTk5OTk4OSw1NzYxNDU1KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDkuMjdzLTI4LjNNQiAgbl4xLjM2LTEuMDIKMTA0TSAoMTA0Mzk1MzAxLDYwMDAwMDApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5Ljgwcy0zOS42TUIgLX0=