Task: Sieve of Pritchard


C++: 



#include <cstring>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctime>

void Extend (uint32_t w[], uint32_t &w_end, uint32_t &length, uint32_t n, bool d[], uint32_t &w_end_max) {
    
    uint32_t i, j, x;
    i = 0; j = w_end;
    x = length + 1; 
    while (x <= n) {
        w[++j] = x; 
        d[x] = false;
        x = length + w[++i];
    }
    length = n; w_end = j;
    if (w_end > w_end_max) w_end_max = w_end;
}

void Delete (uint32_t w[], uint32_t length, uint32_t p, bool d[], uint32_t &imaxf) {
    
    uint32_t i, x;
    i = 0;
    x = p; 
    while (x <= length) {
        d[x] = true; 
        x = p*w[++i];
    }
    imaxf = i-1;
}

void Compress(uint32_t w[], bool d[], uint32_t to, uint32_t &w_end) {
    
    uint32_t i, j;
    j = 0;
    for (i=1; i <= to; i++) {
        if (!d[w[i]]) {
            w[++j] = w[i];
        }
    }
    if (to == w_end) {
        w_end = j;
    } else {
        for (uint32_t k=j+1; k <= to; k++) w[k] = 0;
    }
}

void Sift(uint32_t N, bool printPrimes, uint32_t &nrPrimes, uint32_t &vBound) {
    
    uint32_t *w = new uint32_t[N/4+5];
    bool *d = new bool[N+1];
    uint32_t w_end, length;
    
    
    
    
    uint32_t w_end_max, p, imaxf;
    
    w_end = 0; w[0] = 1;
    w_end_max = 0;
    length = 2;
    
    nrPrimes = 1;
    if (printPrimes) printf("%d", 2);
    p = 3;
    
    
    while (p*p <= N) {
        
        nrPrimes++;
        if (printPrimes) printf(" %d", p);
        if (length < N) {
            
            Extend (w, w_end, length, std::min(p*length,N), d, w_end_max);
        }
        Delete(w, length, p, d, imaxf);
        Compress(w, d, (length < N ? w_end : imaxf), w_end);
        
        p = w[1];
        if (p == 0) break; 
        
    }
    if (length < N) {
        
        Extend (w, w_end, length, N, d, w_end_max);
    }
    
    for (uint32_t i=1; i <= w_end; i++) {
        if (w[i] == 0 || d[w[i]]) continue;
        if (printPrimes) printf(" %d", w[i]);
        nrPrimes++;
    }
    vBound = w_end_max+1;
}

int main (int argc, char *argw[]) {
    bool error = false;
    bool printPrimes = false;
    uint32_t N, nrPrimes, vBound;
    if (argc == 3) {
        if (strcmp(argw[2], "-p") == 0) {
            printPrimes = true;
            argc--;
        } else {
            error = true;
        }
    }
    if (argc == 2) {
        N = atoi(argw[1]);
        if (N < 2 || N > 1000000000) error = true;
    } else {
        error = true;
    }
    if (error) {
        printf("call with: %s N -p where 2 <= N <= 1000000000 and -p to print the primes is optional \n", argw[0]);
        exit(1);
    }
    int start_s = clock();
    Sift(N, printPrimes, nrPrimes, vBound);
    int stop_s=clock();
    printf("\n%d primes up to %lu found in %.3f ms using array w[%d]\n", nrPrimes,
      (unsigned long)N, (stop_s-start_s)*1E3/double(CLOCKS_PER_SEC), vBound);
}


C#: using System;
using System.Collections.Generic;

class Program {

    
    static List<int> PrimesUpTo(int limit, bool verbose = false) {
        var sw = System.Diagnostics.Stopwatch.StartNew();
        var members = new SortedSet<int>{ 1 };
        int stp = 1, prime = 2, n, nxtpr, rtlim = 1 + (int)Math.Sqrt(limit), nl, ac = 2, rc = 1;
        List<int> primes = new List<int>(), tl = new List<int>();
        while (prime < rtlim) {
            nl = Math.Min(prime * stp, limit);
            if (stp < limit) {
                tl.Clear(); 
                foreach (var w in members)
                    for (n = w + stp; n <= nl; n += stp) tl.Add(n);
                members.UnionWith(tl); ac += tl.Count;
            }
            stp = nl; 
            nxtpr = 5; 
            tl.Clear();
            foreach (var w in members) {
                if (nxtpr == 5 && w > prime) nxtpr = w;
                if ((n = prime * w) > nl) break; else tl.Add(n);
            }
            foreach (var itm in tl) members.Remove(itm); rc += tl.Count;
            primes.Add(prime);
            prime = prime == 2 ? 3 : nxtpr;
        }
        members.Remove(1); primes.AddRange(members); sw.Stop();
        if (verbose) Console.WriteLine("Up to {0}, added:{1}, removed:{2}, primes counted:{3}, time:{4} ms", limit, ac, rc, primes.Count, sw.Elapsed.TotalMilliseconds);
        return primes;
    }

    static void Main(string[] args) {
        Console.WriteLine("[{0}]", string.Join(", ", PrimesUpTo(150, true)));
        PrimesUpTo(1000000, true);
    }
}