Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module primerange;
- import std.math: sqrt;
- import std.algorithm: canFind, reverse;
- import std.array: split;
- import std.conv: to, ConvException;
- /// A class designed for calculating prime numbers.
- /// It can be iterated over, resulting in an infinite series of primes.
- /// There is still much room to improve the design, mainly relating to speed.
- class PrimeRange {
- /// Constructor with optional parameter ensuring primes extend to `initMax` before use.
- this(long initMax = 0) {
- while(knownPrimes[$-1] < initMax) getNextPrime();
- }
- /// A list of all primes currently known to the instance
- long[] knownPrimes = [2, 3, 5, 7, 11, 13, 17, 19]; // initialize small primes
- private void getNextPrime() {
- auto candidate = knownPrimes[$-1] + 2; // first potential prime above those in the list
- while (!isPrime(candidate)) candidate += 2; // slow but easy way to increment
- knownPrimes ~= candidate;
- }
- /// Ensure that the number of stored primes is at least `len`
- void ensureLength(uint len) {
- while (knownPrimes.length < len) getNextPrime();
- }
- /// Returns: whether the input number is prime
- bool isPrime(long num) {
- if (num == 2) return true; // special case!
- if (num % 2 == 0) return false;
- if (num <= 1) return false;
- auto numsqrt = sqrt(cast(double)num);
- while (knownPrimes[$-1] < numsqrt) getNextPrime();
- foreach (i; knownPrimes) {
- if (i > numsqrt) break;
- if (num % i == 0) return false;
- }
- return true; // if it passes those tests, it's prime
- }
- /// Main functionality of the class is here
- /// Returns: a slice of prime numbers in the range [min, max)
- long[] primeRange(long min, long max)
- in {
- assert(min <= max, "The minimum must be less than or equal to the maximum.");
- } body {
- while (max > knownPrimes[$-1]) getNextPrime();
- long[] primesWithinRange;
- // TODO: maybe there's a better way to get the range here?
- foreach (i; knownPrimes) {
- if (i < min) continue; // ignore primes < min
- if (i >= max) break; // ignore primes >= max
- primesWithinRange ~= i;
- }
- return primesWithinRange;
- }
- private int primeCounter = 0; // where the 'front' of iteration currently is
- /// empty value for use as a range
- enum empty = false;
- /// front() function for use as a range
- long front() @property const {
- return knownPrimes[primeCounter];
- }
- /// popFront() function for use as a range
- void popFront() {
- ++primeCounter;
- if (knownPrimes.length <= primeCounter) {
- getNextPrime();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement