mirror of
https://bitbucket.org/Mattrixwv/projecteulerjava.git
synced 2025-12-06 17:13:58 -05:00
149 lines
4.3 KiB
Java
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
|
|
*/
|