//ProjectEuler/ProjectEulerCPP/Source/Problem23.cpp //Matthew Ellison // Created: 11-09-18 //Modified: 07-09-20 //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/myClasses /* Copyright (C) 2020 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 . */ #include #include #include #include #include #include "Stopwatch.hpp" #include "Algorithms.hpp" #include "../Headers/Problem23.hpp" //The largest possible number that can not be written as the sum of two abundant numbers int Problem23::MAX_NUM = 28123; //A function that returns true if num can be created by adding two elements from abund and false if it cannot bool Problem23::isSum(const std::vector& abund, int num){ int64_t sum = 0; //Pick a number for the first part of the sum for(unsigned int firstNum = 0;firstNum < abund.size();++firstNum){ //Pick a number for the second part of the sum for(unsigned int secondNum = firstNum;secondNum < abund.size();++secondNum){ sum = abund.at(firstNum) + abund.at(secondNum); if(sum == num){ return true; } else if(sum > num){ break; } } } //If you have run through the entire list and did not find a sum then it is false return false; } //Reserve the size of the vector to speed up insertion void Problem23::reserveVectors(){ //This makes sure the vector is the correct size divisorSums.reserve(MAX_NUM + 1); divisorSums.resize(MAX_NUM + 1); } //Constructor Problem23::Problem23() : Problem("Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers"), sum(0){ reserveVectors(); } //Solve the problem void Problem23::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 <= MAX_NUM;++cnt){ std::vector div = mee::getDivisors(cnt); if(div.size() > 1){ div.pop_back(); //Remove the last element, which is the number itself. This gives us the propper divisors } divisorSums.at(cnt) = mee::getSum(div); } //Get the abundant numbers std::vector abund; for(unsigned int cnt = 0;cnt < divisorSums.size();++cnt){ if(divisorSums.at(cnt) > cnt){ abund.push_back(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 <= MAX_NUM;++cnt){ if(!isSum(abund, cnt)){ sum += cnt; } } //Stop the timer timer.stop(); //Throw a flag to show the problem is solved solved = true; } //Reset the problem so it can be run again void Problem23::reset(){ Problem::reset(); sum = 0; divisorSums.clear(); reserveVectors(); } //Return a string with the solution to the problem std::string Problem23::getString() const{ //If the problem hasn't been solved throw an exception if(!solved){ throw unsolved(); } std::stringstream results; results << "The answer is " << sum; return results.str(); } //Returns the sum of the numbers asked for uint64_t Problem23::getSum() const{ //If the problem hasn't been solved throw an exception if(!solved){ throw unsolved(); } return sum; }