From 3e82e697082f75aa68749738382bad4ceff5b156 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Sun, 7 Feb 2021 12:41:24 -0500 Subject: [PATCH] Added solution to problem 33 --- headers/ProblemSelection.hpp | 4 +- headers/Problems/Problem33.hpp | 69 +++++++++++++++ makefile | 4 +- src/Problems/Problem33.cpp | 156 +++++++++++++++++++++++++++++++++ 4 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 headers/Problems/Problem33.hpp create mode 100644 src/Problems/Problem33.cpp diff --git a/headers/ProblemSelection.hpp b/headers/ProblemSelection.hpp index 7b917cc..5461ac2 100644 --- a/headers/ProblemSelection.hpp +++ b/headers/ProblemSelection.hpp @@ -58,6 +58,7 @@ #include "Problems/Problem30.hpp" #include "Problems/Problem31.hpp" #include "Problems/Problem32.hpp" +#include "Problems/Problem33.hpp" #include "Problems/Problem67.hpp" @@ -65,7 +66,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, 67}; + 31, 32, 33, 67}; //This function returns a pointer to a problem of type number Problem* getProblem(unsigned int problemNumber){ @@ -105,6 +106,7 @@ Problem* getProblem(unsigned int problemNumber){ case 30 : problem = new Problem30; break; case 31 : problem = new Problem31; break; case 32 : problem = new Problem32; break; + case 33 : problem = new Problem33; break; case 67 : problem = new Problem67; break; } diff --git a/headers/Problems/Problem33.hpp b/headers/Problems/Problem33.hpp new file mode 100644 index 0000000..04ff3ee --- /dev/null +++ b/headers/Problems/Problem33.hpp @@ -0,0 +1,69 @@ +//ProjectEuler/ProjectEulerCPP/headers/Problems/Problem33.hpp +//Matthew Ellison +// Created: 02-05-2021 +//Modified: 02-05-2021 +/* +The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s +We shall consider fractions like, 30/50 = 3/5, to be trivial examples +There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator +If the product of these four fractions is given in its lowest common terms, find the value of the denominator +*/ +//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 PROBLEM33_HPP +#define PROBLEM33_HPP + + +#include +#include +#include +#include "Problem.hpp" + + +class Problem33: public Problem{ +private: + //Variables + //Static variables + static int MIN_NUMERATOR; //The lowest the numerator can be + static int MAX_NUMERATOR; //The highest the numerator can be + static int MIN_DENOMINATOR; //The lowest the denominator can be + static int MAX_DENOMINATOR; //The highest the denominator can be + //Instance variables + std::vector numerators; //Holds the numerators that were found + std::vector denominators; //Holds the denominators that were found + int prodDenominator; //Holds the answer to the question +public: + //Constructor + Problem33(); + //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 with the solution to the problem + std::vector getNumerators(); //Returns the list of numerators + std::vector getDenominators(); //Returns the list of denominators + int getProdDenominator(); //Returns the answer to the question +}; + +/* Results: +The denominator of the product is 100 +It took an average of 69.741 microseconds to run this problem over 100 iterations +*/ + +#endif //PROBLEM33_HPP diff --git a/makefile b/makefile index 34e6e04..692dc19 100644 --- a/makefile +++ b/makefile @@ -1,9 +1,9 @@ NUMCORES = $(shell grep -c "^processor" /proc/cpuinfo) NUMCORESWIN = ${NUMBER_OF_PROCESSORS} LIBFLAGS = -shared -std=c++17 -O3 -fPIC -Wall -EXEFLAGS = -Wall -std=c++11 -O3 -Wl,-rpath,'$$ORIGIN/lib' +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 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 67 SOURCE_DIR = src PROBLEM_DIR = $(SOURCE_DIR)/Problems INCLUDE_DIR = headers diff --git a/src/Problems/Problem33.cpp b/src/Problems/Problem33.cpp new file mode 100644 index 0000000..cf513b8 --- /dev/null +++ b/src/Problems/Problem33.cpp @@ -0,0 +1,156 @@ +//ProjectEuler/ProjectEulerCPP/src/Problems/Problem33.cpp +//Matthew Ellison +// Created: 02-05-2021 +//Modified: 02-06-2021 +/* +The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s +We shall consider fractions like, 30/50 = 3/5, to be trivial examples +There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator +If the product of these four fractions is given in its lowest common terms, find the value of the denominator +*/ +//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 +#include "Problems/Problem33.hpp" +#include "Algorithms.hpp" + + +//The lowest the numerator can be +int Problem33::MIN_NUMERATOR = 10; +//The highest the numerator can be +int Problem33::MAX_NUMERATOR = 98; +//The lowest the denominator can be +int Problem33::MIN_DENOMINATOR = 11; +//The highest the denominator can be +int Problem33::MAX_DENOMINATOR = 99; + +//Constructor +Problem33::Problem33() : Problem("If the product of these four fractions is given in its lowest common terms, find the value of the denominator"){ + prodDenominator = 1; +} + +//Operational functions +//Solve the problem +void Problem33::solve(){ + //If the problem has already been solved do nothing and end the function + if(solved){ + return; + } + //Start the timer + timer.start(); + + //Search every possible numerator/denominator pair + for(int denominator = MIN_DENOMINATOR;denominator <= MAX_DENOMINATOR;++denominator){ + for(int numerator = MIN_NUMERATOR;(numerator < denominator) && (numerator <= MAX_NUMERATOR);++numerator){ + std::string denom = std::to_string(denominator); + std::string num = std::to_string(numerator); + int tempNum = 0; + int tempDenom = 1; + + //Check that this isn't a trivial example + if((num[1] == '0') && (denom[1] == '0')){ + continue; + } + //Remove the offending digits if they exist + else if(num[0] == denom[0]){ + tempNum = num[1] - 48; + tempDenom = denom[1] - 48; + } + else if(num[0] == denom[1]){ + tempNum = num[1] - 48; + tempDenom = denom[0] - 48; + } + else if(num[1] == denom[0]){ + tempNum = num[0] - 48; + tempDenom = denom[1] - 48; + } + else if(num[1] == denom[1]){ + tempNum = num[0] - 48; + tempDenom = denom[0] - 48; + } + + //Test if the new fraction is the same as the old one + if(((double)tempNum / (double)tempDenom) == ((double)numerator / (double)denominator)){ + numerators.push_back(numerator); + denominators.push_back(denominator); + } + } + } + + //Get the product of the numbers + int numProd = mee::getProduct(numerators); + int denomProd = mee::getProduct(denominators); + //Get the gcd to reduce to lowest terms + int gcd = std::gcd(numProd, denomProd); + //Save the denominator + prodDenominator = denomProd / gcd; + + //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 Problem33::reset(){ + Problem::reset(); + numerators.clear(); + denominators.clear(); +} + +//Gets +//Return a string with the solution to the problem +std::string Problem33::getResult(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + std::stringstream result; + result << "The denominator of the product is " << prodDenominator; + return result.str(); +} +//Returns the list of numerators +std::vector Problem33::getNumerators(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return numerators; +} +//Returns the list of denominators +std::vector Problem33::getDenominators(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return denominators; +} +//Returns the answer to the question +int Problem33::getProdDenominator(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return prodDenominator; +}