//Java/JavaClasses/Algorithms.java //Matthew Ellison // Created: 03-02-19 //Modified: 03-02-19 //This class holds many algorithms that I have found it useful to keep around //As such all of the functions in here are static and meant to be used as stand alone functions /* Copyright (C) 2019 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 . */ package mattrixwv; import java.util.Arrays; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; public class Algorithms{ //This function returns a list with all the prime numbers <= goalNumber public static ArrayList getPrimes(Integer goalNumber){ ArrayList primes = new ArrayList(); //Holds the prime numbers Boolean foundFactor = false; //A flag for whether a factor of the current number has been found //If the numebr is 0 or negative return an empty list if(goalNumber <= 1){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.add(2); } //We cna now start at 3 and skipp all even numbers, because they cannot be prime for(int possiblePrime = 3;possiblePrime <= goalNumber;possiblePrime += 2){ //Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor Double topPossibleFactor = Math.ceil(Math.sqrt(possiblePrime)); //We can safely assume that there will be at least 1 element in the primes list because of 2 being added before this for(int primesCnt = 0;primes.get(primesCnt) <= topPossibleFactor.intValue();){ if((possiblePrime % primes.get(primesCnt)) == 0){ foundFactor = true; break; } else{ ++primesCnt; } //Check if the index has gone out of range if(primesCnt >= primes.size()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.add(possiblePrime); } else{ foundFactor = false; } } //Sort the list before returning it Collections.sort(primes); return primes; } public static ArrayList getPrimes(BigInteger goalNumber){ ArrayList primes = new ArrayList(); //Holds the prime numbers Boolean foundFactor = false; //A flag for whether a factor of the current number has been found //If the numeber is 1, 0 or negative return an empty list if(goalNumber.compareTo(BigInteger.valueOf(1)) <= 0){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.add(BigInteger.valueOf(2)); } //We cna now start at 3 and skipp all even numbers, because they cannot be prime for(BigInteger possiblePrime = BigInteger.valueOf(3);possiblePrime.compareTo(goalNumber) <= 0;possiblePrime = possiblePrime.add(BigInteger.valueOf(2))){ //Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor BigInteger topPossibleFactor = possiblePrime.sqrt().add(BigInteger.valueOf(1)); //We can safely assume that there will be at least 1 element in the primes list because of 2 being added before this for(int primesCnt = 0;primes.get(primesCnt).compareTo(topPossibleFactor) <= 0;){ if((possiblePrime.mod(primes.get(primesCnt))) == BigInteger.valueOf(0)){ foundFactor = true; break; } else{ ++primesCnt; } //Check if the index has gone out of range if(primesCnt >= primes.size()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.add(possiblePrime); } else{ foundFactor = false; } } //Sort the list before returning it Collections.sort(primes); return primes; } //This function gets a certain number of primes public static ArrayList getNumPrimes(int numberOfPrimes){ ArrayList primes = new ArrayList(); //Holds the prime numbers Boolean foundFactor = false; //A flag for whether a factor of the current number has been found //If the numebr is 0 or negative return an empty list if(numberOfPrimes <= 1){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.add(2); } //We cna now start at 3 and skipp all even numbers, because they cannot be prime for(int possiblePrime = 3;primes.size() < numberOfPrimes;possiblePrime += 2){ //Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor Double topPossibleFactor = Math.ceil(Math.sqrt(possiblePrime)); //We can safely assume that there will be at least 1 element in the primes list because of 2 being added before this for(int primesCnt = 0;primes.get(primesCnt) <= topPossibleFactor.intValue();){ if((possiblePrime % primes.get(primesCnt)) == 0){ foundFactor = true; break; } else{ ++primesCnt; } //Check if the index has gone out of range if(primesCnt >= primes.size()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.add(possiblePrime); } else{ foundFactor = false; } } //Sort the list before returning it Collections.sort(primes); return primes; } public static ArrayList getNumPrimes(BigInteger numberOfPrimes){ ArrayList primes = new ArrayList(); //Holds the prime numbers Boolean foundFactor = false; //A flag for whether a factor of the current number has been found //If the numebr is 0 or negative return an empty list if(numberOfPrimes.compareTo(BigInteger.valueOf(1)) <= 0){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.add(BigInteger.valueOf(2)); } //We cna now start at 3 and skipp all even numbers, because they cannot be prime for(BigInteger possiblePrime = BigInteger.valueOf(3);numberOfPrimes.compareTo((BigInteger.valueOf(primes.size()))) > 0;possiblePrime = possiblePrime.add(BigInteger.valueOf(2))){ //Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor BigInteger topPossibleFactor = possiblePrime.sqrt().add(BigInteger.valueOf(1)); //We can safely assume that there will be at least 1 element in the primes list because of 2 being added before this for(int primesCnt = 0;primes.get(primesCnt).compareTo(topPossibleFactor) <= 0;){ if((possiblePrime.mod(primes.get(primesCnt))) == BigInteger.valueOf(0)){ foundFactor = true; break; } else{ ++primesCnt; } //Check if the index has gone out of range if(primesCnt >= primes.size()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.add(possiblePrime); } else{ foundFactor = false; } } //Sort the list before returning it Collections.sort(primes); return primes; } //This function returns all factors of goalNumber public static ArrayList getFactors(int goalNumber){ //You need to get all the primes that could be factors of this number so you can test them Double topPossiblePrime = Math.ceil(Math.sqrt(goalNumber)); ArrayList primes = getPrimes(topPossiblePrime.intValue()); ArrayList factors = new ArrayList(); //You need to step through each prime and see if it is a factor in the number for(int cnt = 0;cnt < primes.size();){ //If the prime is a factor you need to add it to the factor list if((goalNumber % primes.get(cnt)) == 0){ factors.add(primes.get(cnt)); goalNumber /= primes.get(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; } } //If you didn't get any factors the number itself must be a prime if(factors.size() == 0){ factors.add(goalNumber); goalNumber /= goalNumber; } //If for some reason the goalNumber is not 1 throw an error ///Need to add the appropriate error here //Return the list of factors return factors; } public static ArrayList getFactors(BigInteger goalNumber){ //You need to get all the primes that could be factors of this number so you can test them BigInteger topPossiblePrime = goalNumber.sqrt(); ArrayList primes = getPrimes(topPossiblePrime); ArrayList factors = new ArrayList(); //You need to step through each prime and see if it is a factor in the number for(int cnt = 0;cnt < primes.size();){ //If the prime is a factor you need to add it to the factor list if((goalNumber.mod(primes.get(cnt))).compareTo(BigInteger.valueOf(0)) == 0){ factors.add(primes.get(cnt)); goalNumber = goalNumber.divide(primes.get(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; } } //If you didn't get any factors the number itself must be a prime if(factors.size() == 0){ factors.add(goalNumber); goalNumber.divide(goalNumber); } //If for some reason the goalNumber is not 1 throw an error ///Need to add the appropriate error here //Return the list of factors return factors; } //This function returns all the divisors of goalNumber public static ArrayList getDivisors(int goalNumber){ ArrayList divisors = new ArrayList(); //Start by checking that the number is positive if(goalNumber <= 0){ return divisors; } //If the number is 1 return just itself else if(goalNumber == 1){ divisors.add(1); } //Otherwise add 1 and itself to the list else{ divisors.add(1); divisors.add(goalNumber); } //Start at 3 and loop through all numbers < sqrt(goalNumber) looking for a number that divides it evenly Double topPossibleDivisor = Math.ceil(Math.sqrt(goalNumber)); for(Integer possibleDivisor = 2;possibleDivisor <= topPossibleDivisor;++possibleDivisor){ //If you find one add it and the number it creates to the list if((goalNumber % possibleDivisor) == 0){ divisors.add(possibleDivisor); //Accound for the possibility of sqrt(goalNumber) being a divisor if(possibleDivisor != topPossibleDivisor.intValue()){ divisors.add(goalNumber / possibleDivisor); } } } //Sort the list before returning it for neatness Collections.sort(divisors); //Return the list return divisors; } public static ArrayList getDivisors(BigInteger goalNumber){ ArrayList divisors = new ArrayList(); //Start by checking that the number is positive if(goalNumber.compareTo(BigInteger.valueOf(0)) <= 0){ return divisors; } //If the number is 1 return just itself else if(goalNumber.equals(BigInteger.valueOf(1))){ divisors.add(BigInteger.valueOf(1)); } //Otherwise add 1 and itself to the list else{ divisors.add(BigInteger.valueOf(1)); divisors.add(goalNumber); } //Start at 3 and loop through all numbers < sqrt(goalNumber) looking for a number that divides it evenly BigInteger topPossibleDivisor = goalNumber.sqrt(); for(BigInteger possibleDivisor = BigInteger.valueOf(2);possibleDivisor.compareTo(topPossibleDivisor) <= 0;possibleDivisor = possibleDivisor.add(BigInteger.valueOf(1))){ //If you find one add it and the number it creates to the list if(goalNumber.mod(possibleDivisor).equals(BigInteger.valueOf(0))){ divisors.add(possibleDivisor); //Accound for the possibility of sqrt(goalNumber) being a divisor if(!possibleDivisor.equals(topPossibleDivisor)){ divisors.add(goalNumber.divide(possibleDivisor)); } } } //Sort the list before returning it for neatness Collections.sort(divisors); //Return the list return divisors; } //This function returns all the divisors of goalNumber public static Integer getFib(int goalSubscript){ //Setup the variables Integer[] fibNums = {1, 1, 0}; //A list to keep track of the Fibonacci numbers. It need only be 3 long because we only need the one we are working on and the last 2 //If the number is <= 0 return 0 if(goalSubscript <= 0){ return 0; } //Loop through the list, generating Fibonacci numbers until it finds the correct subscript Integer fibLoc = 2; for(fibLoc = 2;fibLoc < goalSubscript;++fibLoc){ fibNums[fibLoc % 3] = fibNums[(fibLoc - 1) % 3] + fibNums[(fibLoc - 2) % 3]; } //Return the propper number. The location counter is 1 off of the subscript return fibNums[(fibLoc - 1) % 3]; } public static BigInteger getFib(BigInteger goalSubscript){ //Setup the variables BigInteger[] fibNums = {BigInteger.valueOf(1), BigInteger.valueOf(1), BigInteger.valueOf(0)}; //A list to keep track of the Fibonacci numbers. It need only be 3 long because we only need the one we are working on and the last 2 //If the number is <= 0 return 0 if(goalSubscript.compareTo(BigInteger.valueOf(0)) <= 0){ return BigInteger.valueOf(0); } //Loop through the list, generating Fibonacci numbers until it finds the correct subscript Integer fibLoc = 2; for(fibLoc = 2;goalSubscript.compareTo(BigInteger.valueOf(fibLoc)) > 0;++fibLoc){ fibNums[fibLoc % 3] = fibNums[(fibLoc - 1) % 3].add(fibNums[(fibLoc - 2) % 3]); } //Return the propper number. The location counter is 1 off of the subscript return fibNums[(fibLoc - 1) % 3]; } //This function returns a list of all Fibonacci numbers <= goalNumber public static ArrayList getAllFib(int goalNumber){ //Setup the variables ArrayList fibNums = new ArrayList(); //A list to save the Fibonacci numbers //If the number is <= 0 return an empty list if(goalNumber <= 0){ return fibNums; } //This means that at least 2 1's are elements fibNums.add(1); fibNums.add(1); //Loop to generate the rest of the Fibonacci numbers while(fibNums.get(fibNums.size() - 1) <= goalNumber){ fibNums.add(fibNums.get(fibNums.size() - 1) + fibNums.get(fibNums.size() - 2)); } //At this point the most recent number is > goalNumber, so remove it and return the rest of the list fibNums.remove(fibNums.size() - 1); return fibNums; } public static ArrayList getAllFib(BigInteger goalNumber){ //Setup the variables ArrayList fibNums = new ArrayList(); //A list to save the Fibonacci numbers //If the number is <= 0 return an empty list if(goalNumber.compareTo(BigInteger.valueOf(0)) <= 0){ return fibNums; } //This means that at least 2 1's are elements fibNums.add(BigInteger.valueOf(1)); fibNums.add(BigInteger.valueOf(1)); //Loop to generate the rest of the Fibonacci numbers while(fibNums.get(fibNums.size() - 1).compareTo(goalNumber) <= 0){ fibNums.add(fibNums.get(fibNums.size() - 1).add(fibNums.get(fibNums.size() - 2))); } //At this point the most recent number is > goalNumber, so remove it and return the rest of the list fibNums.remove(fibNums.size() - 1); return fibNums; } //This function returns the sum of all elements in the list public static int getSum(ArrayList nums){ //If a blank list was passed to the function return 0 as the sum if(nums.size() == 0){ return 0; } //Setup the variables Integer sum = 0; //Loop through every element in the list and add them together for(Integer num : nums){ sum += num; } //Return the sum of all elements return sum; } public static BigInteger getBigSum(ArrayList nums){ //If a blank list was passed to the function return 0 as the sum if(nums.size() == 0){ return BigInteger.valueOf(0); } //Setup the variables BigInteger sum = BigInteger.valueOf(0); //Loop through every element in the list and add them together for(BigInteger num : nums){ sum = sum.add(num); } //Return the sum of all elements return sum; } //This function returns the product of all elements in the list public static int getProd(ArrayList nums){ //If a blank list was passed tot he fuction return 0 as the product if(nums.size() == 0){ return 0; } //Setup the variables Integer product = 1; //Start at 1 because x * 1 = x //Loop through every element in the list and multiply them together for(Integer num : nums){ product *= num; } //Return the product of all elements return product; } public static BigInteger getBigProd(ArrayList nums){ //If a blank list was passed tot he fuction return 0 as the product if(nums.size() == 0){ return BigInteger.valueOf(0); } //Setup the variables BigInteger product = BigInteger.valueOf(1); //Start at 1 because x * 1 = x //Loop through every element in the list and multiply them together for(BigInteger num : nums){ product = product.multiply(num); } //Return the product of all elements return product; } }