diff --git a/headers/ProblemSelection.hpp b/headers/ProblemSelection.hpp index 3cc81b0..5a32270 100644 --- a/headers/ProblemSelection.hpp +++ b/headers/ProblemSelection.hpp @@ -60,6 +60,7 @@ #include "Problems/Problem32.hpp" #include "Problems/Problem33.hpp" #include "Problems/Problem34.hpp" +#include "Problems/Problem35.hpp" #include "Problems/Problem67.hpp" @@ -67,7 +68,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, 67}; + 31, 32, 33, 34, 35, 67}; //This function returns a pointer to a problem of type number Problem* getProblem(unsigned int problemNumber){ @@ -109,6 +110,7 @@ Problem* getProblem(unsigned int problemNumber){ case 32 : problem = new Problem32; break; case 33 : problem = new Problem33; break; case 34 : problem = new Problem34; break; + case 35 : problem = new Problem35; break; case 67 : problem = new Problem67; break; } diff --git a/headers/Problems/Problem34.hpp b/headers/Problems/Problem34.hpp index 2ec53d5..75d00d1 100644 --- a/headers/Problems/Problem34.hpp +++ b/headers/Problems/Problem34.hpp @@ -45,7 +45,7 @@ public: 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 + virtual std::string getResult(); //Return a string with the 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 }; diff --git a/headers/Problems/Problem35.hpp b/headers/Problems/Problem35.hpp new file mode 100644 index 0000000..fca6d1d --- /dev/null +++ b/headers/Problems/Problem35.hpp @@ -0,0 +1,61 @@ +//ProjectEuler/ProjectEulerCPP/headers/Problems/Problem35.hpp +//Matthew Ellison +// Created: 06-02-21 +//Modified: 06-02-21 +//How many circular primes are there below one million? +//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 PROBLEM35_HPP +#define PROBLEM35_HPP + + +#include +#include +#include "Problem.hpp" + + +class Problem35 : public Problem{ +private: + //Variables + //Static variables + static int MAX_NUM; //The largest number that we are checking for primes + //Instance variables + std::vector primes; //The primes below MAX_NUM + std::vector circularPrimes; //The circular primes below MAX_NUM + //Functions + std::vector getRotations(std::string str); //This function returns a list of all rotations of a string passed to it +public: + //Constructor + Problem35(); + //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 solutino to the problem + std::vector getPrimes(); //Returns the vector of primes < MAX_NUM + std::vector getCircularPrimes(); //Returns the vector of circular primes < MAX_NUM + int getNumCircularPrimes(); //Returns the number of circular primes +}; + +/* Results: +The number of all circular prime numbers under 999999 is 55 +It took an average of 2.618 seconds to run this problem over 100 iterations +*/ + +#endif //PROBLEM35_HPP diff --git a/headers/benchmark.hpp b/headers/benchmark.hpp index 2b546b0..338eb37 100644 --- a/headers/benchmark.hpp +++ b/headers/benchmark.hpp @@ -42,7 +42,7 @@ std::string getBenchmarkResults(Problem* problem, double totalTime, unsigned int //Variables //Valid menu options enum BENCHMARK_OPTIONS {RUN_SPECIFIC = 1, RUN_ALL_SHORT, RUN_ALL, BENCHMARK_EXIT, BENCHMARK_SIZE}; -std::vector tooLong = {5, 15, 23, 24, 29}; //The list of problems that take "too long" to run. (Over 1 second on my machine) +std::vector tooLong = {5, 15, 23, 24, 29, 35}; //The list of problems that take "too long" to run. (Over 1 second on my machine) //The driver function for the benchmark selection diff --git a/makefile b/makefile index ba1a781..1ed1cd8 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 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 67 SOURCE_DIR = src PROBLEM_DIR = $(SOURCE_DIR)/Problems INCLUDE_DIR = headers diff --git a/src/Problems/Problem35.cpp b/src/Problems/Problem35.cpp new file mode 100644 index 0000000..045291b --- /dev/null +++ b/src/Problems/Problem35.cpp @@ -0,0 +1,129 @@ +//ProjectEuler/ProjectEulerCPP/src/Problems/Problem35.cpp +//Matthew Ellison +// Created: 06-02-21 +//Modified: 06-02-21 +//How many circular primes are there below one million? +//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 . +*/ +//TODO: This could possibly be improved by adding all rotations at the same time and removing them from the list +//TODO: This could also be improved by skipping any prime that includes 2, 4, 5, 6, 8, or 0 + + +#include +#include +#include "Problems/Problem35.hpp" +#include "Algorithms.hpp" + + +//The largest number that we are checking for primes +int Problem35::MAX_NUM = 999999; + +//Function +//This function returns a list of all rotations of a string passed to it +std::vector Problem35::getRotations(std::string str){ + std::vector rotations; + rotations.push_back(str); + for(unsigned long cnt = 1;cnt < str.size();++cnt){ + str = str.substr(1) + str[0]; + rotations.push_back(str); + } + return rotations; +} + +//Constructor +Problem35::Problem35() : Problem("How many circular primes are there below one million?"){ +} + +//Operational functions +//Solve the problem +void Problem35::solve(){ + //If the problem has already been solved do nothing and end the function + if(solved){ + return; + } + + //Start the timer + timer.start(); + + //Get all primes under 1,000,000 + primes = mee::getPrimes(MAX_NUM); + //Go through all primes, get all their rotations, and check if those numbers are also primes + for(int prime : primes){ + bool allRotationsPrime = true; + //Get all of the rotations of the prime and see if they are also prime + std::vector rotations = getRotations(std::to_string(prime)); + for(std::string rotation : rotations){ + int p = std::stoi(rotation); + if(!mee::isFound(primes, p)){ + allRotationsPrime = false; + break; + } + } + //If all rotations are prime add it to the list of circular primes + if(allRotationsPrime){ + circularPrimes.push_back(prime); + } + } + + //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 Problem35::reset(){ + Problem::reset(); + primes.clear(); + circularPrimes.clear(); +} +//Gets +//Returns a string with the solutino to the problem +std::string Problem35::getResult(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + std::stringstream result; + result << "The number of all circular prime numbers under " << MAX_NUM << " is " << circularPrimes.size(); + return result.str(); +} +//Returns the vector of primes < MAX_NUM +std::vector Problem35::getPrimes(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return primes; +} +//Returns the vector of circular primes < MAX_NUM +std::vector Problem35::getCircularPrimes(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return circularPrimes; +} +//Returns the number of circular primes +int Problem35::getNumCircularPrimes(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return circularPrimes.size(); +}