Sieve of Pritchard: Difference between revisions

→‎C#: Limit on wheel expansion was incorrect. Old version had proper output, but went about it in the wrong way.
(→‎{{header|J}}: work around some details of J's historical implementation of sparse arrays to better match the spirit of this sieve)
(→‎C#: Limit on wheel expansion was incorrect. Old version had proper output, but went about it in the wrong way.)
Line 28:
 
=={{header|C#|CSharp}}==
Loosely based on the Python version. I cut a couple of things out and it still worked. Not too crazy about having to create temporary lists to add or remove from the HashSetSortedSet, seems inefficient. But that is the work-around I employed, since HashSetsSortedSets can't be accessed by indexing, and are non-mutable in a foreach loop. I haven't yet directly tested this against a Sieve of Eratosthenes to compare performance. The Wikipedia article suggests using a doubly linked list, so this C# incarnation is a kludge at best.
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
Line 36:
// Returns list of primes up to limit using Pritchard (wheel) sieve
static List<int> PrimesUpTo(int limit) {
var members = new HashSetSortedSet<int>{ 1 };
int stp = 1, prime = 2, n, npnxtpr, rtlim = 1 + (int)Math.Sqrt(limit), nl = 2;
var primes = new List<int>();
while (prime <= rtlim) {
if (stp < limit) {
var nu = new List<int>();
foreach (var w in members) {
for (n = w + stp; n <= nl; n += stp) nu.Add(n);
while (n <= limit) { nu.Add(n); n += stp; }
}
members.UnionWith(nu);
}
stp = Math.Min(prime * stp, limit);
npnxtpr = 0; // for obtaining the next prime
var wb = new List<int>();
foreach (var w in members) {
if (npnxtpr == 0 && w > prime) npnxtpr = w; // next prime
if (members.Contains(n = prime * w)) wb.Add(n);
}
foreach (var itm in wb) if (members.Contains(itm)) members.Remove(itm);
primes.Add(prime);
prime = prime == 2 ? 3 : npnxtpr;
nl = Math.Min(limit, prime * stp);
}
members.Remove(1);