Latest revision as of 12:26, 20 May 2020

Contents

Implicit Heap

The following is an original implicit heap implementation for the sieve of
Eratosthenes, kept here for historical record. Also, it implements more sophisticated, lazier scheduling. The Prime_numbers#Tree merging with Wheel section simplifies it, removing the People a structure altogether, and improves upon it by using a wheel optimization.

Prime Wheels

The idea of only testing odd numbers can be extended further. For instance, it is a useful fact that every prime number other than 2 and 3 must be of the form or . Thus, we only need to test these numbers:

Here, prs is the list of primes greater than 3 and isPrime does not test for divisibility by 2 or 3 because the candidates by construction don't have these numbers as factors. We also need to exclude 1 from the candidates and mark the next one as prime to start the recursion.

Such a scheme to generate candidate numbers first that avoid a given set of primes as divisors is called a prime wheel. Imagine that you had a wheel of circumference 6 to be rolled along the number line. With spikes positioned 1 and 5 units around the circumference, rolling the wheel will prick holes exactly in those positions on the line whose numbers are not divisible by 2 and 3.

A wheel can be represented by its circumference and the spiked positions.

dataWheel=WheelInteger[Integer]

We prick out numbers by rolling the wheel.

roll(Wheelnrs)=[n*k+r|k<-[0..],r<-rs]

The smallest wheel is the unit wheel with one spike, it will prick out every number.

w0=Wheel1[1]

We can create a larger wheel by rolling a smaller wheel of circumference n along a rim of circumference p*n while excluding spike positions at multiples of p.

Using IntSet for a traditional sieve

moduleSievewhereimportqualifiedData.IntSetasI-- findNext - finds the next member of an IntSet.findNextcis|I.membercis=c|c>I.findMaxis=error"Ooops. No next number in set."|otherwise=findNext(c+1)is-- mark - delete all multiples of n from n*n to the end of the setmarknis=isI.\\(I.fromAscList(takeWhile(<=end)(map(n*)[n..])))whereend=I.findMaxis-- primes - gives all primes up to n primesn=worker2(I.fromAscList[2..n])whereworkerxis|(x*x)>n=is|otherwise=worker(findNext(x+1)is)(markxis)