Given n, find m such that m is the smallest semiprime greater than n.
Next prime is pretty straightforward, semiprime is less so. To be clear, only the semiprime is needed, though getting the factors at the same time would be convenient.
I've thought of a few approaches but I'm sure there are better ones.
Arithmetic operations are assumed to be O(1). I used Sieve of Eratosthenes, which is O(n log log n), I am aware of the Sieve of Atkin but I like my semi-optimized Eratosthenes.
1. Counting up from n
Count up from n, stop when you find a semiprime.
This seems really dumb but if there's an O(log n) semiprime test or O(1) test given primes below, this may be faster than the other 2.
Semiprime distribution appears to be much higher than prime distribution, so with a good semiprime test this might actually be better than O(n).
2. Primes counting down
Define prev(x) and next(x) and giving the previous and next primes respectively, which can be O(log n) if the primes are stored in a tree or with list binary search.
First do sieve.
Start with p=prev(sqrt(n)) and q=next(n/p). While pq<=n, go to the next q. If pq is less than the minimum so far, record it as the new minimum. Move on to the previous p until you run out of p to test.
This is guaranteed to find the correct answer but it's rather slow. Still O(n log n) though, so maybe acceptable.
3. Primes counting up
Start with sieve as usual. Create a hash set view of the sieve for O(1) primality tests.
Begin with p=2. Iterate through the primes up to sqrt(n). For each p, get q=(((n/p+1)/2)*2)+1=(((n/p+1)>>1)<<1)|1. While pq is less than the minimum so far and q is not prime, add 2 to q. If pq is still less than the minimum, record it as the new minimum.
I implemented #1 and #3 in Java, both using the same Sieve of Eratosthenes implementation. Most of the running time is spent sieving, so if there's optimizations to be done it's in the sieve. After some optimizations, counting up (#1) beat primes counting up (#3), being twice as fast in the last and largest test (11 decimal digit n).
There is still hope though, because how far the sieve needs to be extended depends on the largest number to prime test. If a semiprime test with a lower prime testing bound exists, the counting method may prove to be even faster.
Surely there is a better algorithm? Or at least a better way to implement this one?
n
be? – Maurya