package main
import (
"container/heap"
"fmt"
)
func main() {
p := newP()
for i := 1; i < 1000000; i++ {
p()
}
fmt.Println("1,000,000th prime:", p())
}
func newP() func() int {
n := 1
var pq pQueue
top := &pMult{2, 4, 0}
return func() int {
for {
n++
if n < top.pMult { // n is a new prime
heap.Push(&pq, &pMult{prime: n, pMult: n * n})
top = pq[0]
return n
}
// n was next on the queue, it's a composite
for top.pMult == n {
top.pMult += top.prime
heap.Fix(&pq, 0)
top = pq[0]
}
}
}
}
type pMult struct {
prime int
pMult int
index int
}
type pQueue []*pMult
func (q pQueue) Len() int { return len(q) }
func (q pQueue) Less(i, j int) bool { return q[i].pMult < q[j].pMult }
func (q pQueue) Swap(i, j int) {
q[i], q[j] = q[j], q[i]
q[i].index = i
q[j].index = j
}
func (p *pQueue) Push(x interface{}) {
q := *p
e := x.(*pMult)
e.index = len(q)
*p = append(q, e)
}
func (p *pQueue) Pop() interface{} {
q := *p
last := len(q) - 1
e := q[last]
*p = q[:last]
return e
}
cGFja2FnZSBtYWluCiAKaW1wb3J0ICgKICAgICJjb250YWluZXIvaGVhcCIKICAgICJmbXQiCikKIApmdW5jIG1haW4oKSB7CiAgICBwIDo9IG5ld1AoKQogICAgZm9yIGkgOj0gMTsgaSA8IDEwMDAwMDA7IGkrKyB7CiAgICAgICAgcCgpCiAgICB9CiAgICBmbXQuUHJpbnRsbigiMSwwMDAsMDAwdGggcHJpbWU6IiwgcCgpKQp9CiAKZnVuYyBuZXdQKCkgZnVuYygpIGludCB7CiAgICBuIDo9IDEKICAgIHZhciBwcSBwUXVldWUKICAgIHRvcCA6PSAmcE11bHR7MiwgNCwgMH0KICAgIHJldHVybiBmdW5jKCkgaW50IHsKICAgICAgICBmb3IgewogICAgICAgICAgICBuKysKICAgICAgICAgICAgaWYgbiA8IHRvcC5wTXVsdCB7IC8vIG4gaXMgYSBuZXcgcHJpbWUKICAgICAgICAgICAgICAgIGhlYXAuUHVzaCgmcHEsICZwTXVsdHtwcmltZTogbiwgcE11bHQ6IG4gKiBufSkKICAgICAgICAgICAgICAgIHRvcCA9IHBxWzBdCiAgICAgICAgICAgICAgICByZXR1cm4gbgogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIG4gd2FzIG5leHQgb24gdGhlIHF1ZXVlLCBpdCdzIGEgY29tcG9zaXRlCiAgICAgICAgICAgIGZvciB0b3AucE11bHQgPT0gbiB7CiAgICAgICAgICAgICAgICB0b3AucE11bHQgKz0gdG9wLnByaW1lCiAgICAgICAgICAgICAgICBoZWFwLkZpeCgmcHEsIDApCiAgICAgICAgICAgICAgICB0b3AgPSBwcVswXQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CiAKdHlwZSBwTXVsdCBzdHJ1Y3QgewogICAgcHJpbWUgaW50CiAgICBwTXVsdCBpbnQKICAgIGluZGV4IGludAp9CiAKdHlwZSBwUXVldWUgW10qcE11bHQKIApmdW5jIChxIHBRdWV1ZSkgTGVuKCkgaW50ICAgICAgICAgICB7IHJldHVybiBsZW4ocSkgfQpmdW5jIChxIHBRdWV1ZSkgTGVzcyhpLCBqIGludCkgYm9vbCB7IHJldHVybiBxW2ldLnBNdWx0IDwgcVtqXS5wTXVsdCB9CmZ1bmMgKHEgcFF1ZXVlKSBTd2FwKGksIGogaW50KSB7CiAgICBxW2ldLCBxW2pdID0gcVtqXSwgcVtpXQogICAgcVtpXS5pbmRleCA9IGkKICAgIHFbal0uaW5kZXggPSBqCn0KZnVuYyAocCAqcFF1ZXVlKSBQdXNoKHggaW50ZXJmYWNle30pIHsKICAgIHEgOj0gKnAKICAgIGUgOj0geC4oKnBNdWx0KQogICAgZS5pbmRleCA9IGxlbihxKQogICAgKnAgPSBhcHBlbmQocSwgZSkKfQpmdW5jIChwICpwUXVldWUpIFBvcCgpIGludGVyZmFjZXt9IHsKICAgIHEgOj0gKnAKICAgIGxhc3QgOj0gbGVuKHEpIC0gMQogICAgZSA6PSBxW2xhc3RdCiAgICAqcCA9IHFbOmxhc3RdCiAgICByZXR1cm4gZQp9