//JavaClasses/src/main/java/mattrixwv/SieveOfEratosthenes.java
//Matthew Ellison
// Created: 06-30-21
//Modified: 08-11-24
//This class uses to Sieve of Eratosthenes to generate an infinite number of primes
/*
Copyright (C) 2024 Matthew Ellison
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see
* This implementation generates prime numbers in an incremental fashion using a modified version of the Sieve of Eratosthenes algorithm. * The algorithm uses a map to keep track of the multiples of found prime numbers to efficiently determine the next prime. *
*/ public class SieveOfEratosthenes implements Iterator* This method always returns {@code true} as the iterator is designed to * generate primes indefinitely. *
* * @return {@code true}, as the iterator can generate an infinite number of primes */ @Override public boolean hasNext(){ return true; } /** * Returns the next prime number. * ** The method generates the next prime number by checking and updating the * internal map of known multiples. The first prime returned is 2, and subsequent * primes are found by incrementing the possible prime number and checking its * primality using the map. *
* * @return the next prime number * @throws NoSuchElementException if the next prime cannot be represented by a {@code long} */ @Override public Long next(){ long prime; //If this is the first run just return 2 if(possiblePrime == 2){ prime = possiblePrime++; return prime; } //Loop until you find a prime number for(;dict.containsKey(possiblePrime);possiblePrime += 2){ //Create the next entry for all entries in the map for(long num : dict.get(possiblePrime)){ if(!dict.containsKey(possiblePrime + num + num)){ dict.put(possiblePrime + num + num, new ArrayList<>(Arrays.asList(num))); } else{ dict.get(possiblePrime + num + num).add(num); } } //Delete the current entry dict.remove(possiblePrime); } //Protect against overflows if(possiblePrime < 0){ throw new NoSuchElementException("the next prime cannot be described by a long"); } //Save that the number is a prime prime = possiblePrime; //Add the next entry to the prime dictionary dict.put(prime * 3, new ArrayList<>(Arrays.asList(prime))); //Move on to the next possible prime possiblePrime += 2; return prime; } }