--luaClasses/Algorithms.lua --Matthew Ellison -- Created: 2-4-19 --Modified: 2-7-19 --This is a file of algorithms that I have found it useful to keep around at all times --This function returns a list with all the primes numbers <= goalNumber function getPrimes(goalNumber) local primes = {}; --Holds the prime numbers local foundFactor = false; --If the number is 0 or negative return an empty table if(goalNumber <= 1) then return primes; --Otherwise the number is at lease 2, therefore 2 should be added to the list else primes[#primes + 1] = 2; end --We can now start at 3 and skip all even numbers, because they cannot be prime for possiblePrime=3,goalNumber,2 do --Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor primesCnt = 1; --We can safely assume that there will be at least 1 element in the primes list because of 2 being added before the loop topPossibleFactor = math.ceil(math.sqrt(possiblePrime)) while(primes[primesCnt] <= topPossibleFactor) do if((possiblePrime % primes[primesCnt]) == 0) then foundFactor = true; break; else primesCnt = primesCnt + 1; end --Check if the index has gone out of range if(primesCnt >= #primes) then break; end end --If you didn't find a factor then the current number must be prime if(not foundFactor) then primes[#primes + 1] = possiblePrime; else foundFactor = false; end end --Sort the array just to be neat and safe table.sort(primes); --Return the array return primes; end --This function gets a specific number of primes function getNumPrimes(numberOfPrimes) local primes = {}; --Holds the prime numbers local foundFactor = false; --If the number is 0 or negative return an empty table if(numberOfPrimes <= 1) then return primes; --Otherwise the number is at lease 2, therefore 2 should be added to the list else primes[#primes + 1] = 2; end --We can now start at 3 and skip all even numbers, because they cannot be prime possiblePrime = 3; while((#primes < numberOfPrimes) and (possiblePrime >= 0)) do --Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor primesCnt = 1; --We can safely assume that there will be at least 1 element in the primes list because of 2 being added before the loop topPossibleFactor = math.ceil(math.sqrt(possiblePrime)) while(primes[primesCnt] <= topPossibleFactor) do if((possiblePrime % primes[primesCnt]) == 0) then foundFactor = true; break; else primesCnt = primesCnt + 1; end --Check if the index has gone out of range if(primesCnt >= #primes) then break; end end --If you didn't find a factor then the current number must be prime if(not foundFactor) then primes[#primes + 1] = possiblePrime; else foundFactor = false; end --Advance to the next possible prime number possiblePrime = possiblePrime + 2; end --Sort the array just to be neat and safe table.sort(primes); --Return the array return primes; end --This is a function that returns all the factors of goalNumber function getFactors(goalNumber) local primes = getPrimes(math.ceil(math.sqrt(goalNumber))); --Get all the primes up the largest possible divisor local factors = {}; --Holds all the factors --You need to step through each prime and see if it is a factor of the number cnt = 1; while((cnt <= #primes) and (goalNumber > 1)) do --If the prime is a factor you need to add it to the factor list if((goalNumber % primes[cnt]) == 0) then factors[#factors + 1] = primes[cnt]; goalNumber = goalNumber / primes[cnt]; --Otherwise advance the location in the primes array you are looking at --By not advancing if the primes is a factor you allow for multiple of the same prime number as a factor else cnt = cnt + 1 end end --If you didn't get any factors the number itself must be a prime number if(#factors == 0) then factors[#factors + 1] = goalNumber; goalNumber = 1 end --If your some reason teh goalNumber is not 1 print an error message if(goalNumber > 1) then print("There was an error in getFactors(). A leftover of " .. goalNumber); end --Return the list of factors return factors; end --This is a function the returns all divisors of the number passed to it function getDivisors(goalNumber) local divisors = {}; --Start by checking that the number is positive if(goalNumber <= 0) then return divisors; --If the number is 1 return just itself elseif(goalNumber == 1) then divisors[#divisors+1] = 1; --Otherwise add 1 and itself to the list else divisors[#divisors+1] = 1; divisors[#divisors+1] = goalNumber; end --Start at 3 and loop through all numbers < (goalNumber / 2) looking for a number that divides it evenly local topPossibleDivisor = math.ceil(math.sqrt(goalNumber)); for possibleDivisor=2,topPossibleDivisor do --If you find one add it and the number it creates to the list if((goalNumber % possibleDivisor) == 0) then divisors[#divisors+1] = possibleDivisor; --Account for the possibility of sqrt(goalNumber) being a divisor if(possibleDivisor ~= topPossibleDivisor) then divisors[#divisors + 1] =(goalNumber / possibleDivisor); end end end --Sort the list before returning for neatness table.sort(divisors); --Return the list return divisors; end