Files
ProjectEulerJava/src/main/java/com/mattrixwv/project_euler/problems/Problem23.java
2023-06-30 21:59:11 -04:00

149 lines
4.3 KiB
Java

//ProjectEulerJava/src/main/java/mattrixwv/ProjectEuler/Problems/Problem23.java
//Matthew Ellison
// Created: 03-22-19
//Modified: 06-27-23
//Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers
//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/JavaClasses
/*
Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
*/
package com.mattrixwv.project_euler.problems;
import com.mattrixwv.ArrayAlgorithms;
import com.mattrixwv.NumberAlgorithms;
import java.util.ArrayList;
import java.util.List;
public class Problem23 extends Problem{
//Variables
//Static variables
protected static int maxNum = 28123; //The largest number to be checked
//Instance variables
protected ArrayList<Integer> divisorSums; //This gives the sum of the divisors at subscripts
protected long sum; //The sum of all the numbers we are looking for
//Functions
//Constructor
public Problem23(){
super("Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers");
divisorSums = new ArrayList<>();
reserveArray();
sum = 0;
}
//Operational functions
//Reserve the size of the array to speed up insertion
private void reserveArray(){
divisorSums.ensureCapacity(maxNum); //It is faster to reserve the appropriate amount of ram now
//Make sure every element has a 0 in it's location
while(divisorSums.size() <= maxNum){
divisorSums.add(0);
}
}
//Solve the problem
@Override
public void solve(){
//If the problem has already been solved do nothing and end the function
if(solved){
return;
}
//Start the timer
timer.start();
//Get the sum of the divisors of all numbers < MAX_NUM
for(int cnt = 1;cnt < maxNum;++cnt){
List<Integer> div = NumberAlgorithms.getDivisors(cnt);
//Remove the last element, which is the number itself. This gives us the propper divisors
if(div.size() > 1){
div.remove(div.size() - 1);
}
divisorSums.set(cnt, ArrayAlgorithms.getSum(div));
}
//Get the abundant numbers
ArrayList<Integer> abund = new ArrayList<>();
for(int cnt = 0;cnt < divisorSums.size();++cnt){
if(divisorSums.get(cnt) > cnt){
abund.add(cnt);
}
}
//Check if each number can be the sum of 2 abundant numbers and add to the sum if no
for(int cnt = 1;cnt < maxNum;++cnt){
if(!isSum(abund, cnt)){
sum += cnt;
}
}
//Stop the timer
timer.stop();
//Throw a flag to show the problem is solved
solved = true;
}
//A function that returns true if num can be created by adding two elements from abund and false if it cannot
private boolean isSum(final ArrayList<Integer> abund, int num){
int tempSum = 0;
//Pick a number for the first part of the sum
for(int firstNum = 0;firstNum < abund.size();++firstNum){
//Pick a number for the second part of the sum
for(int secondNum = firstNum;secondNum < abund.size();++secondNum){
tempSum = abund.get(firstNum) + abund.get(secondNum);
if(tempSum == num){
return true;
}
else if(tempSum > num){
break;
}
}
}
//If you have run through the entire list and did not find a sum then it is false
return false;
}
//Reset the problem so it can be run again
@Override
public void reset(){
super.reset();
divisorSums.clear();
reserveArray();
sum = 0;
}
//Gets
//Returns the result of solving the problem
@Override
public String getResult(){
solvedCheck("result");
return String.format("The answer is %d", sum);
}
//Returns the sum of the numbers asked for
public long getSum(){
solvedCheck("sum");
return sum;
}
}
/* Results:
The answer is 4179871
It took an average of 15.048 seconds to run this problem through 100 iterations
*/