Added solution to problem 33

This commit is contained in:
2021-02-07 12:41:24 -05:00
parent d751e584f3
commit 3e82e69708
4 changed files with 230 additions and 3 deletions

View File

@@ -58,6 +58,7 @@
#include "Problems/Problem30.hpp" #include "Problems/Problem30.hpp"
#include "Problems/Problem31.hpp" #include "Problems/Problem31.hpp"
#include "Problems/Problem32.hpp" #include "Problems/Problem32.hpp"
#include "Problems/Problem33.hpp"
#include "Problems/Problem67.hpp" #include "Problems/Problem67.hpp"
@@ -65,7 +66,7 @@
std::vector<unsigned int> PROBLEM_NUMBERS = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, std::vector<unsigned int> PROBLEM_NUMBERS = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 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 //This function returns a pointer to a problem of type number
Problem* getProblem(unsigned int problemNumber){ Problem* getProblem(unsigned int problemNumber){
@@ -105,6 +106,7 @@ Problem* getProblem(unsigned int problemNumber){
case 30 : problem = new Problem30; break; case 30 : problem = new Problem30; break;
case 31 : problem = new Problem31; break; case 31 : problem = new Problem31; break;
case 32 : problem = new Problem32; break; case 32 : problem = new Problem32; break;
case 33 : problem = new Problem33; break;
case 67 : problem = new Problem67; break; case 67 : problem = new Problem67; break;
} }

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
#ifndef PROBLEM33_HPP
#define PROBLEM33_HPP
#include <cinttypes>
#include <string>
#include <vector>
#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<int> numerators; //Holds the numerators that were found
std::vector<int> 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<int> getNumerators(); //Returns the list of numerators
std::vector<int> 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

View File

@@ -1,9 +1,9 @@
NUMCORES = $(shell grep -c "^processor" /proc/cpuinfo) NUMCORES = $(shell grep -c "^processor" /proc/cpuinfo)
NUMCORESWIN = ${NUMBER_OF_PROCESSORS} NUMCORESWIN = ${NUMBER_OF_PROCESSORS}
LIBFLAGS = -shared -std=c++17 -O3 -fPIC -Wall 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 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 SOURCE_DIR = src
PROBLEM_DIR = $(SOURCE_DIR)/Problems PROBLEM_DIR = $(SOURCE_DIR)/Problems
INCLUDE_DIR = headers INCLUDE_DIR = headers

156
src/Problems/Problem33.cpp Normal file
View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
#include <cinttypes>
#include <numeric>
#include <string>
#include <sstream>
#include <vector>
#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<int> 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<int> 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;
}