diff --git a/headers/ProblemSelection.hpp b/headers/ProblemSelection.hpp index 5461ac2..3cc81b0 100644 --- a/headers/ProblemSelection.hpp +++ b/headers/ProblemSelection.hpp @@ -59,6 +59,7 @@ #include "Problems/Problem31.hpp" #include "Problems/Problem32.hpp" #include "Problems/Problem33.hpp" +#include "Problems/Problem34.hpp" #include "Problems/Problem67.hpp" @@ -66,7 +67,7 @@ std::vector PROBLEM_NUMBERS = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 67}; + 31, 32, 33, 34, 67}; //This function returns a pointer to a problem of type number Problem* getProblem(unsigned int problemNumber){ @@ -107,6 +108,7 @@ Problem* getProblem(unsigned int problemNumber){ case 31 : problem = new Problem31; break; case 32 : problem = new Problem32; break; case 33 : problem = new Problem33; break; + case 34 : problem = new Problem34; break; case 67 : problem = new Problem67; break; } diff --git a/headers/Problems/Problem34.hpp b/headers/Problems/Problem34.hpp new file mode 100644 index 0000000..2ec53d5 --- /dev/null +++ b/headers/Problems/Problem34.hpp @@ -0,0 +1,58 @@ +//ProjectEuler/ProjectEulerCPP/headers/Problems/Problem34.hpp +//Matthew Ellison +// Created: 06-01-21 +//Modified: 06-01-21 +//Find the sum of all numbers which are equal to the sum of the factorial of their digits +//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/myClasses +/* + Copyright (C) 2021 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 . +*/ + +#ifndef PROBLEM34_HPP +#define PROBLEM34_HPP + + +#include +#include +#include "Problem.hpp" + + +class Problem34 : public Problem{ +private: + //Variables + //Static variables + static int MAX_NUM; //The largest num that can be the sum of its own digits + //Instance variables + std::vector factorials; //Holds the pre-computed factorials of the numbers 0-9 + int sum; //Holds the sum of all numbers equal to the sum of their digit's factorials +public: + //Constructor + Problem34(); + //Operational functions + virtual void solve(); //Solve the problem + virtual void reset(); //Reset the problem so it can be run again + //Gets + virtual std::string getResult(); //Return a string witht he solution to the problem + std::vector getFactorials(); //Returns the list of factorials from 0-9 + int getSum(); //Returns the sum of all numbers equal to the sum of their digit's factorials +}; + +/* Results: +The sum of all numbers that are the sum of their digit's factorials is 40730 +It took an average of 15.181 milliseconds to run this problem over 100 iterations +*/ + +#endif //PROBLEM34_HPP diff --git a/makefile b/makefile index 692dc19..ba1a781 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ NUMCORESWIN = ${NUMBER_OF_PROCESSORS} LIBFLAGS = -shared -std=c++17 -O3 -fPIC -Wall EXEFLAGS = -Wall -std=c++17 -O3 -Wl,-rpath,'$$ORIGIN/lib' LINKEDLIBS = -lgmp -lgmpxx -PROBLEM_NUMBERS = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 67 +PROBLEM_NUMBERS = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 67 SOURCE_DIR = src PROBLEM_DIR = $(SOURCE_DIR)/Problems INCLUDE_DIR = headers diff --git a/src/Problems/Problem34.cpp b/src/Problems/Problem34.cpp new file mode 100644 index 0000000..8db4dbe --- /dev/null +++ b/src/Problems/Problem34.cpp @@ -0,0 +1,113 @@ +//ProjectEuler/ProjectEulerCPP/src/Problems/Problem34.cpp +//Matthew Ellison +// Created: 06-01-21 +//Modified: 06-01-21 +//Find the sum of all numbers which are equal to the sum of the factorial of their digits +//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/myClasses +/* + Copyright (C) 2021 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 "Problems/Problem34.hpp" +#include "Algorithms.hpp" + + +//The largest num that can be the sum of its own digits +int Problem34::MAX_NUM = 1499999; + +//Constructor +Problem34::Problem34() : Problem("Find the sum of all numbers which are equal to the sum of the factorial of their digits"){ + sum = 0; + factorials.reserve(10); //Reserve a size of 10 so that factorials[x] = x! + factorials.resize(10); +} + +//Operational functions +//Solve the problem +void Problem34::solve(){ + //If the problem has already been solved do nothing and end the function + if(solved){ + return; + } + + //Start the timer + timer.start(); + + //Pre-compute the possible factorials from 0! to 9! + for(int cnt = 0;cnt <= 9;++cnt){ + factorials[cnt] = mee::factorial(cnt); + } + //Run through all possible numbers from 3-MAX_NUM and see if they equal the sum of their digit's factorials + for(int cnt = 3;cnt < MAX_NUM;++cnt){ + //Split the number into its digits and add each one to the sum + std::string numString = std::to_string(cnt); + int currentSum = 0; + for(char number : numString){ + int num = number - 48; + currentSum += factorials[num]; + } + //If the number is equal to the sum add the sum to the running sum + if(currentSum == cnt){ + sum += currentSum; + } + } + + //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 Problem34::reset(){ + Problem::reset(); + sum = 0; + factorials.clear(); + factorials.reserve(10); + factorials.resize(10); +} + +//Gets +//Return a string with the solution to the problem +std::string Problem34::getResult(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + std::stringstream result; + result << "The sum of all numbers that are the sum of their digit's factorials is " << sum; + return result.str(); +} +//Returns the list of factorials from 0-9 +std::vector Problem34::getFactorials(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return factorials; +} +//Returns the sum of all numbers equal to the sum of their digit's factorials +int Problem34::getSum(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return sum; +}