Advertisement
Guest User

Untitled

a guest
Dec 9th, 2016
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.69 KB | None | 0 0
  1. module primerange;
  2.  
  3. import std.math: sqrt;
  4. import std.algorithm: canFind, reverse;
  5. import std.array: split;
  6. import std.conv: to, ConvException;
  7.  
  8. /// A class designed for calculating prime numbers.
  9. /// It can be iterated over, resulting in an infinite series of primes.
  10. /// There is still much room to improve the design, mainly relating to speed.
  11. class PrimeRange {
  12.  
  13. /// Constructor with optional parameter ensuring primes extend to `initMax` before use.
  14. this(long initMax = 0) {
  15. while(knownPrimes[$-1] < initMax) getNextPrime();
  16. }
  17.  
  18. /// A list of all primes currently known to the instance
  19. long[] knownPrimes = [2, 3, 5, 7, 11, 13, 17, 19]; // initialize small primes
  20.  
  21. private void getNextPrime() {
  22. auto candidate = knownPrimes[$-1] + 2; // first potential prime above those in the list
  23. while (!isPrime(candidate)) candidate += 2; // slow but easy way to increment
  24. knownPrimes ~= candidate;
  25. }
  26.  
  27. /// Ensure that the number of stored primes is at least `len`
  28. void ensureLength(uint len) {
  29. while (knownPrimes.length < len) getNextPrime();
  30. }
  31.  
  32. /// Returns: whether the input number is prime
  33. bool isPrime(long num) {
  34. if (num == 2) return true; // special case!
  35. if (num % 2 == 0) return false;
  36. if (num <= 1) return false;
  37.  
  38. auto numsqrt = sqrt(cast(double)num);
  39. while (knownPrimes[$-1] < numsqrt) getNextPrime();
  40.  
  41. foreach (i; knownPrimes) {
  42. if (i > numsqrt) break;
  43. if (num % i == 0) return false;
  44. }
  45.  
  46. return true; // if it passes those tests, it's prime
  47.  
  48. }
  49.  
  50. /// Main functionality of the class is here
  51. /// Returns: a slice of prime numbers in the range [min, max)
  52. long[] primeRange(long min, long max)
  53. in {
  54. assert(min <= max, "The minimum must be less than or equal to the maximum.");
  55. } body {
  56. while (max > knownPrimes[$-1]) getNextPrime();
  57. long[] primesWithinRange;
  58.  
  59. // TODO: maybe there's a better way to get the range here?
  60. foreach (i; knownPrimes) {
  61. if (i < min) continue; // ignore primes < min
  62. if (i >= max) break; // ignore primes >= max
  63. primesWithinRange ~= i;
  64. }
  65.  
  66. return primesWithinRange;
  67.  
  68. }
  69.  
  70. private int primeCounter = 0; // where the 'front' of iteration currently is
  71.  
  72. /// empty value for use as a range
  73. enum empty = false;
  74.  
  75. /// front() function for use as a range
  76. long front() @property const {
  77. return knownPrimes[primeCounter];
  78. }
  79.  
  80. /// popFront() function for use as a range
  81. void popFront() {
  82. ++primeCounter;
  83. if (knownPrimes.length <= primeCounter) {
  84. getNextPrime();
  85. }
  86. }
  87.  
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement