Skip to content

Instantly share code, notes, and snippets.

@ikkentim
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ikkentim/ffa58ba9274615a19bc1 to your computer and use it in GitHub Desktop.
Save ikkentim/ffa58ba9274615a19bc1 to your computer and use it in GitHub Desktop.
A prime generator. I think it works all right
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace Primer
{
class PrimeGenerator
{
private readonly BigInteger _checkStep = 5000;
private static IEnumerable<BigInteger> GetBigIntegers(BigInteger start)
{
while (true)
yield return start++;
}
private static IEnumerable<BigInteger> GetMultiples(BigInteger number, BigInteger min, BigInteger max)
{
for (var n = (min/number)*number; n < max; n += number)
yield return n;
}
public IEnumerable<BigInteger> GetPrimes()
{
/*
* nonPrimes contains a list of number that are not primes.
* This list is filled by multiplying all known prime numbers by any number.
*/
List<BigInteger> nonPrimes = new List<BigInteger>();
/*
* checkLimit is the number up to which nonPrimes have yet been calculated.
*/
BigInteger checkLimit = _checkStep;
/*
* primes contains a list of found primes.
*/
List<BigInteger> primes = new List<BigInteger>();
/*
* Loop trough an infinite list of integers, starting at 2.
* For this reason, this function should be used with linq (eg. x.Take(n))
*/
foreach(var number in GetBigIntegers(2)){
/*
* If this number is outside of nonPrimes boundaries, generate a new set.
*/
if (number == checkLimit)
{
/*
* Replace the set with a new set of all multiples of the found primes.
*/
var min = checkLimit;
checkLimit += _checkStep;
nonPrimes.Clear();
foreach (var p in primes.Where(p => p < checkLimit / 2))
nonPrimes.AddRange(GetMultiples(p, min, checkLimit));
}
/*
* If the number is in the nonPrimes list, it is not a prime.
*/
if (nonPrimes.Contains(number)) continue;
/*
* Add the number to the known primes list and return the number.
*/
primes.Add(number);
yield return number;
/*
* Add all multiples of this prime to the nonPrimes list.
*/
if (checkLimit > number*2)
nonPrimes.AddRange(GetMultiples(number, number, checkLimit));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment