mirror of
https://bitbucket.org/Mattrixwv/pyclasses.git
synced 2025-12-06 18:33:58 -05:00
Added prime number generator
This commit is contained in:
111
Algorithms.py
111
Algorithms.py
@@ -20,8 +20,38 @@ Copyright (C) 2019 Matthew Ellison
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
#Generate an infinite sequence of prime numbers using the Sieve of Eratosthenes
|
||||||
|
#Based on code by David Eppstein found at https://code.activestate.com/recipes/117119/
|
||||||
|
def primeGenerator():
|
||||||
|
#Return 2 the first time, this lets us skip all even numbers later
|
||||||
|
yield 2
|
||||||
|
|
||||||
|
#Map composite integers to primes witnessing their compositeness
|
||||||
|
dict = {}
|
||||||
|
|
||||||
|
#Start checking for primes with the number 3
|
||||||
|
possiblePrime = 3
|
||||||
|
while True:
|
||||||
|
#If q is not in the dictionary it is a new prime number
|
||||||
|
#Return it and mark it's next multiple
|
||||||
|
if possiblePrime not in dict:
|
||||||
|
yield possiblePrime
|
||||||
|
dict[possiblePrime * possiblePrime] = [possiblePrime]
|
||||||
|
#If q is in the dictionary it is a composite number
|
||||||
|
else:
|
||||||
|
#Move each witness to it's next multiple
|
||||||
|
for num in dict[possiblePrime]:
|
||||||
|
dict.setdefault(num + possiblePrime, []).append(num)
|
||||||
|
#We no longer need this, free the memory
|
||||||
|
del dict[possiblePrime]
|
||||||
|
|
||||||
|
#Skip all multiples of 2
|
||||||
|
possiblePrime += 2
|
||||||
|
|
||||||
#This function returns a list with all the prime numbers <= goalNumber
|
#This function returns a list with all the prime numbers <= goalNumber
|
||||||
def getPrimes(goalNumber: int) -> list:
|
def getPrimes(goalNumber: int) -> list:
|
||||||
primes = []
|
primes = []
|
||||||
@@ -61,78 +91,29 @@ def getPrimes(goalNumber: int) -> list:
|
|||||||
|
|
||||||
#This function gets a certain number of primes
|
#This function gets a certain number of primes
|
||||||
def getNumPrimes(numberOfPrimes: int) -> list:
|
def getNumPrimes(numberOfPrimes: int) -> list:
|
||||||
|
gen = primeGenerator()
|
||||||
|
#gen = postponed_sieve()
|
||||||
primes = []
|
primes = []
|
||||||
foundFactor = False
|
for _ in range(1, numberOfPrimes + 1):
|
||||||
|
primes.append(next(gen))
|
||||||
#If the number is 0 or negative return an empty list
|
|
||||||
if(numberOfPrimes < 1):
|
|
||||||
return primes
|
|
||||||
#Otherwise there is at lease 1, meaning 2 will be the first entry
|
|
||||||
else:
|
|
||||||
primes.append(2)
|
|
||||||
|
|
||||||
#Loop through every odd number starting at 3 until you reach the correct number of entries looking for a prime number
|
|
||||||
possiblePrime = 3 #Holds the next possible prime number
|
|
||||||
while((len(primes) < numberOfPrimes) and (possiblePrime > 0)):
|
|
||||||
#Loop through all primes we have already found, up to sqrt(possiblePrime), checking for a factor
|
|
||||||
primesCnt = 0
|
|
||||||
#We can safely assume that there will at lease be 1 element in the primes list because of 2 being added before the loop
|
|
||||||
topPossibleFactor = math.ceil(math.sqrt(possiblePrime))
|
|
||||||
while(primes[primesCnt] <= topPossibleFactor):
|
|
||||||
#If you find a factor the number is not a prime so raise the flag and break the loop
|
|
||||||
if((possiblePrime % primes[primesCnt]) == 0):
|
|
||||||
foundFactor = True
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
primesCnt += 1
|
|
||||||
#Check if the index has gone out of bounds and break the loop if it has
|
|
||||||
if(primesCnt >= len(primes)):
|
|
||||||
break
|
|
||||||
|
|
||||||
#If you don't find a factor then this number is prime so add it to the list
|
|
||||||
if(not foundFactor):
|
|
||||||
primes.append(possiblePrime)
|
|
||||||
#If it wasn't prime simply reset the flag
|
|
||||||
else:
|
|
||||||
foundFactor = False
|
|
||||||
#Increment to the next possible prime number
|
|
||||||
possiblePrime += 2
|
|
||||||
|
|
||||||
#Everything should already be in order, but sort it just in case
|
|
||||||
primes.sort()
|
|
||||||
|
|
||||||
#Return the list with all the prime numbers
|
#Return the list with all the prime numbers
|
||||||
return primes
|
return primes
|
||||||
|
|
||||||
#This is a function that returns all the factors of goalNumber
|
#This is a function that returns all the factors of goalNumber
|
||||||
def getFactors(goalNumber: int) -> list:
|
def getFactors(goalNumber: int) -> list:
|
||||||
#You need to get all the primes up to this number
|
prime_factors_list = []
|
||||||
primes = getPrimes(math.ceil(math.sqrt(goalNumber))) #If there is a prime it must be <= sqrt(num)
|
while goalNumber % 2 == 0:
|
||||||
factors = []
|
prime_factors_list.append(2)
|
||||||
|
goalNumber /= 2
|
||||||
#You need to step through each prime and see if it is a factor in the number
|
for i in range(3, int(math.sqrt(goalNumber))+1, 2):
|
||||||
cnt = 0
|
if goalNumber % i == 0:
|
||||||
while((cnt < len(primes)) and (goalNumber > 1)):
|
prime_factors_list.append(i)
|
||||||
#If the prime is a factor you need to add it to the factor list
|
goalNumber /= i
|
||||||
if((goalNumber % primes[cnt]) == 0):
|
if goalNumber > 2:
|
||||||
factors.append(primes[cnt])
|
prime_factors_list.append(int(goalNumber))
|
||||||
goalNumber /= primes[cnt]
|
prime_factors_list.sort()
|
||||||
#Otherwise advance the location in primes you are looking at
|
return prime_factors_list
|
||||||
#By not advancing if the prime is a factor you allow for multiple of the same prime number as a factor
|
|
||||||
else:
|
|
||||||
cnt += 1
|
|
||||||
|
|
||||||
#If you didn't get any factors the number itself must be a prime
|
|
||||||
if(len(factors) == 0):
|
|
||||||
factors.append(goalNumber)
|
|
||||||
goalNumber /= goalNumber
|
|
||||||
|
|
||||||
#If for some reason the goalNumber is not 0 print an error message
|
|
||||||
if(goalNumber > 1):
|
|
||||||
print("There was an error in getFactors(). A leftover of " + str(goalNumber))
|
|
||||||
|
|
||||||
#Return the list of factors
|
|
||||||
return factors
|
|
||||||
|
|
||||||
#This function returns all the divisors of goalNumber
|
#This function returns all the divisors of goalNumber
|
||||||
def getDivisors(goalNumber: int) -> list:
|
def getDivisors(goalNumber: int) -> list:
|
||||||
|
|||||||
Reference in New Issue
Block a user