#Python/myClasses/Algorithms.py #Matthew Ellison # Created: 1-27-19 #Modified: 1-30-19 #This is a file that contains a few algorithms that I have used several times import math #This function returns a list with all the prime numbers <= goalNumber def getPrimes(goalNumber: int): primes = [] foundFactor = False #If the number is 0 or negative return an empty list if(goalNumber <= 1): return primes #If the number is even 2 is a factor and all other factors will be odd if((goalNumber %2) == 0): primes.append(2) #We can now start at 3 and skip all even numbers, because they cannot be prime for possiblePrime in range(3, goalNumber + 1, 2): #Need goalNumber + 1 to account for goalNumber being prime #Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor 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((possiblePrime % primes[primesCnt]) == 0): foundFactor = True break else: primesCnt += 1 #Check if the index has gone out of range if(primesCnt >= len(primes)): break #If you didn't find a factor then the current number must be prime if(not foundFactor): primes.append(possiblePrime) else: foundFactor = False primes.sort() return primes #This function gets a certain number of primes def getNumPrimes(numberOfPrimes: int): primes = [] foundFactor = False #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 primes #This is a function that returns all the factors of goalNumber def getFactors(goalNumber: int): #You need to get all the primes up to this number primes = getPrimes(math.ceil(math.sqrt(goalNumber))) #If there is a prime it must be <= sqrt(num) factors = [] #You need to step through each prime and see if it is a factor in the number cnt = 0 while((cnt < len(primes)) and (goalNumber > 1)): #If the prime is a factor you need to add it to the factor list if((goalNumber % primes[cnt]) == 0): factors.append(primes[cnt]) goalNumber /= primes[cnt] #Otherwise advance the location in primes you are looking at #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 def getDivisors(goalNumber: int) -> list: divisors = [] #Start by checking that the number is positive if(goalNumber <= 0): return divisors #If the number is 1 return just itself elif(goalNumber == 1): divisors.append(1) #Otherwise add 1 and itself to the list else: divisors.append(1) divisors.append(goalNumber) #Start at 3 and loop through all numbers < (goalNumber / 2 ) looking for a number that divides it evenly topPossibleDivisor = math.ceil(math.sqrt(goalNumber)) for possibleDivisor in range(2, topPossibleDivisor + 1): #Add one because we need <= goalNumber/2 #If you find one add it and the number it creates to the list if((goalNumber % possibleDivisor) == 0): divisors.append(possibleDivisor) #Account for the possibility sqrt(goalNumber) being a divisor if(possibleDivisor != topPossibleDivisor): divisors.append(goalNumber / possibleDivisor) #Sort the list before returning for neatness divisors.sort() #Return the list return divisors