diff --git a/headers/ProblemSelection.hpp b/headers/ProblemSelection.hpp index e7f9bee..947b40c 100644 --- a/headers/ProblemSelection.hpp +++ b/headers/ProblemSelection.hpp @@ -62,6 +62,7 @@ #include "Problems/Problem34.hpp" #include "Problems/Problem35.hpp" #include "Problems/Problem36.hpp" +#include "Problems/Problem37.hpp" #include "Problems/Problem67.hpp" @@ -69,7 +70,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, 34, 35, 36, 67}; + 31, 32, 33, 34, 35, 36, 37, 67}; //This function returns a pointer to a problem of type number Problem* getProblem(unsigned int problemNumber){ @@ -113,6 +114,7 @@ Problem* getProblem(unsigned int problemNumber){ case 34 : problem = new Problem34; break; case 35 : problem = new Problem35; break; case 36 : problem = new Problem36; break; + case 37 : problem = new Problem37; break; case 67 : problem = new Problem67; break; } diff --git a/headers/Problems/Problem36.hpp b/headers/Problems/Problem36.hpp index d8df0dd..e53726e 100644 --- a/headers/Problems/Problem36.hpp +++ b/headers/Problems/Problem36.hpp @@ -40,6 +40,7 @@ private: std::vector palindromes; //All numbers that are palindromes in base 10 and 2 int sum; //The sum of all elements in the vector palindromes public: + //Functions //Constructor Problem36(); //Operational functions diff --git a/headers/Problems/Problem37.hpp b/headers/Problems/Problem37.hpp new file mode 100644 index 0000000..f3d2b90 --- /dev/null +++ b/headers/Problems/Problem37.hpp @@ -0,0 +1,60 @@ +//ProjectEuler/ProjectEulerCPP/headers/Problems/Problem37.hpp +//Matthew Ellison +// Created: 06-30-21 +//Modified: 06-30-21 +//Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted). +//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 PROBLEM37_HPP +#define PROBLEM37_HPP + + +#include +#include +#include "Problem.hpp" + + +class Problem37 : public Problem{ +private: + //Variables + //Static variables + static uint64_t LAST_PRIME_BEFORE_CHECK; //The last prime before 11 since single digit primes aren't checked + //Instance variables + std::vector truncPrimes; //All numbers that are truncatable primes + uint64_t sum; //The sum of all elements in truncPrimes +public: + //Functions + //Constructor + Problem37(); + //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(); //Returns a string with the solution to the problem + std::vector getTruncatablePrimes(); //Returns the list of primes that can be truncated + uint64_t getSumOfPrimes(); //Get the sum of all primes in truncPrimes +}; + +/* Results: +The sum of all left and right truncatable primes is 748317 +It took an average of 63.831 milliseconds to run this problem over 100 iterations +*/ + + +#endif //PROBLEM37_HPP diff --git a/makefile b/makefile index aa5d366..5a946db 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 34 35 36 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 35 36 37 67 SOURCE_DIR = src PROBLEM_DIR = $(SOURCE_DIR)/Problems INCLUDE_DIR = headers diff --git a/src/Problems/Problem36.cpp b/src/Problems/Problem36.cpp index 624d2ab..11d6df0 100644 --- a/src/Problems/Problem36.cpp +++ b/src/Problems/Problem36.cpp @@ -27,7 +27,6 @@ #include #include "Problems/Problem36.hpp" #include "Algorithms.hpp" -#include //The largest number that will be checked diff --git a/src/Problems/Problem37.cpp b/src/Problems/Problem37.cpp new file mode 100644 index 0000000..52f8dfc --- /dev/null +++ b/src/Problems/Problem37.cpp @@ -0,0 +1,152 @@ +//ProjectEuler/ProjectEulerCPP/src/Problems/Problem37.cpp +//Matthew Ellison +// Created: 06-30-21 +//Modified: 06-30-21 +//Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted). +//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 +#include "Problems/Problem37.hpp" +#include "Algorithms.hpp" + + +//The last prime before 11 since single digit primes aren't checked +uint64_t Problem37::LAST_PRIME_BEFORE_CHECK = 7; + +//Constructor +Problem37::Problem37() : Problem("Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted)."), sum(0){ +} + +//Operational functions +//Solve the problem +void Problem37::solve(){ + //If the problem has already been solved do nothing and end the function + if(solved){ + return; + } + + //Start the timer + timer.start(); + + //Create the sieve and get the first prime number + mee::SieveOfEratosthenes sieve; + uint64_t currentPrime = sieve.next(); + //Loop through the sieve until you get to LAST_PRIME_BEFORE_CHECK + while(currentPrime < LAST_PRIME_BEFORE_CHECK){ + currentPrime = sieve.next(); + } + //Loop until truncPrimes contains 11 elements + while(truncPrimes.size() < 11){ + bool isTruncPrime = true; + //Get the next prime + currentPrime = sieve.next(); + //Convert the prime to a string + std::string primeString = std::to_string(currentPrime); + //If the string contains an even digit move to the next prime + for(uint64_t strLoc = 0;(strLoc < primeString.size()) && (isTruncPrime);++strLoc){ + //Allow 2 to be the first digit + if((strLoc == 0) && (primeString[strLoc] == '2')){ + continue; + } + switch(primeString[strLoc]){ + case '0' : + case '2' : + case '4' : + case '6' : + case '8' : isTruncPrime = false; break; + } + } + //Start removing digits from the left and see if the number stays prime + if(isTruncPrime){ + for(uint64_t truncLoc = 1;truncLoc < primeString.size();++truncLoc){ + //Create a substring of the prime, removing the needed digits from the left + std::string primeSubstring = primeString.substr(truncLoc); + //Convert the string to an int and see if the number is still prime + uint64_t newPrime = std::stoull(primeSubstring); + if(!mee::isPrime(newPrime)){ + isTruncPrime = false; + break; + } + } + } + //Start removing digits from the right and see if the number stays prime + if(isTruncPrime){ + for(uint64_t truncLoc = 1;truncLoc < primeString.size();++truncLoc){ + //Create a substring of the prime, removing the needed digits from the right + std::string primeSubstring = primeString.substr(0, primeString.size() - truncLoc); + //Convert the string to an int and see if the number is still prime + uint64_t newPrime = std::stoull(primeSubstring); + if(!mee::isPrime(newPrime)){ + isTruncPrime = false; + break; + } + } + } + //If the number remained prime through all operations add it to the vector + if(isTruncPrime){ + truncPrimes.push_back(currentPrime); + } + } + //Get the sum of all elements in the truncPrimes vector + sum = mee::getSum(truncPrimes); + + //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 Problem37::reset(){ + Problem::reset(); + truncPrimes.clear(); + sum = 0; +} + +//Gets +//Returns a string with the solution to the problem +std::string Problem37::getResult(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + std::stringstream result; + result << "The sum of all left and right truncatable primes is " << sum; + return result.str(); +} +//Returns the list of primes that can be truncated +std::vector Problem37::getTruncatablePrimes(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return truncPrimes; +} +//Get the sum of all primes in truncPrimes +uint64_t Problem37::getSumOfPrimes(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return sum; +}