Last active
August 29, 2015 14:05
-
-
Save ikkentim/ffa58ba9274615a19bc1 to your computer and use it in GitHub Desktop.
A prime generator. I think it works all right
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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