//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; }