From 4e752fb82ca9ca420d692efcf895ec677bd03552 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Tue, 28 Jul 2020 18:14:14 -0400 Subject: [PATCH] Created solution to problem32 --- Headers/Problem32.hpp | 85 ++++++++++++++++++++++++++++++ ProblemSelection.hpp | 4 +- Source/Problem32.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++ makefile | 2 +- 4 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 Headers/Problem32.hpp create mode 100644 Source/Problem32.cpp diff --git a/Headers/Problem32.hpp b/Headers/Problem32.hpp new file mode 100644 index 0000000..1cc2ed8 --- /dev/null +++ b/Headers/Problem32.hpp @@ -0,0 +1,85 @@ +//ProjectEuler/ProjectEulerCPP/Headers/Problem32.hpp +//Matthew Ellison +// Created: 07-27-20 +//Modified: 07-27-20 +//Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital. +//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/myClasses +/* + Copyright (C) 2020 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 PROBLEM32_HPP +#define PROBLEM32_HPP + + +#include +#include +#include +#include "Problem.hpp" + + +class Problem32 : public Problem{ +private: + //Structures + struct ProductSet{ + int multiplicand; + int multiplier; + ProductSet(int multiplicand, int multiplier) : multiplicand(multiplicand), multiplier(multiplier){ + } + int64_t getProduct(){ + return ((int64_t)multiplicand * (int64_t)multiplier); + } + bool operator==(ProductSet secondSet){ + return (getProduct() == secondSet.getProduct()); + } + std::string getNumString(){ + return std::to_string(multiplicand) + std::to_string(multiplier) + std::to_string(getProduct()); + } + }; + + //Variables + //Static variables + static int TOP_MULTIPLICAND; //The largest multiplicand to check + static int TOP_MULTIPLIER; //The largest multiplier to check + //Instance variables + std::vector listOfProducts; //The list of unique products that are 1-9 pandigital + uint64_t sumOfPandigitals; //The sum of the products of the pandigital numbers + + //Functions + //Returns true if the passed productset is 1-9 pandigital + bool isPandigital(ProductSet currentSet); +public: + //Functions + //Constructor + Problem32(); + //Operational functions + //Solve the problem + void solve(); + //Reset the problem so it can be run again + void reset(); + //Gets + //Returns the sum of the pandigitals + int64_t getSumOfPandigitals(); +}; + +/* Results: +There are 7 unique 1-9 pandigitals +The sum of the products of these pandigitals is 45228 +It took an average of 4.480 milliseconds to run this problem over 100 iterations +*/ + + +#endif //PROBLEM32_HPP diff --git a/ProblemSelection.hpp b/ProblemSelection.hpp index d3a26a1..bad5117 100644 --- a/ProblemSelection.hpp +++ b/ProblemSelection.hpp @@ -57,6 +57,7 @@ #include "Headers/Problem29.hpp" #include "Headers/Problem30.hpp" #include "Headers/Problem31.hpp" +#include "Headers/Problem32.hpp" #include "Headers/Problem67.hpp" @@ -64,7 +65,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, 67}; + 31, 32, 67}; //This function returns a pointer to a problem of type number Problem* getProblem(unsigned int problemNumber){ @@ -103,6 +104,7 @@ Problem* getProblem(unsigned int problemNumber){ case 29 : problem = new Problem29; break; case 30 : problem = new Problem30; break; case 31 : problem = new Problem31; break; + case 32 : problem = new Problem32; break; case 67 : problem = new Problem67; break; } diff --git a/Source/Problem32.cpp b/Source/Problem32.cpp new file mode 100644 index 0000000..6960bde --- /dev/null +++ b/Source/Problem32.cpp @@ -0,0 +1,117 @@ +//ProjectEuler/ProjectEulerCPP/Source/Problem32.cpp +//Matthew Ellison +// Created: 07-27-20 +//Modified: 07-27-20 +//Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital. +//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/myClasses +/* + Copyright (C) 2020 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 "Algorithms.hpp" +#include "../Headers/Problem32.hpp" +#include + +int Problem32::TOP_MULTIPLICAND = 99; //The largest multiplicand to check +int Problem32::TOP_MULTIPLIER = 4999; //The largest multiplier to check + + +//Returns true if the passed productset is 1-9 pandigital +bool Problem32::isPandigital(ProductSet currentSet){ + //Get the numbers out of the object and put them into a string + std::string numberString = currentSet.getNumString(); + //Make srue the string is the correct length + if(numberString.size() != 9){ + return false; + } + //Make sure every number from 1-9 is contained exactly once + for(int panNumber = 1;panNumber <= 9;++panNumber){ + //Make sure there is exactly one of this number contained in the string + if(mee::findNumOccurrence(numberString, std::to_string(panNumber)[0]) != 1){ + return false; + } + } + //If all numbers were found in the string return true + return true; +} + +//Constructor +Problem32::Problem32() : Problem("Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital."), sumOfPandigitals(0){ +} + +//Operational functions +//Solve the problem +void Problem32::solve(){ + //If the problem has alread been solved do nothing and end the function + if(solved){ + return; + } + + //Start the timer + timer.start(); + + //Create the multiplicand and start working your way up + for(int multiplicand = 1;multiplicand <= TOP_MULTIPLICAND;++multiplicand){ + //Run through all possible multipliers + for(int multiplier = multiplicand;multiplier <= TOP_MULTIPLIER;++multiplier){ + ProductSet currentProductSet(multiplicand, multiplier); + //If the product is too long move on to the next possible number + if(currentProductSet.getNumString().size() > 9){ + break; + } + //If the current number is a pandigital that doesn't already exist in the list add it to the list + if(isPandigital(currentProductSet)){ + if(std::find(listOfProducts.begin(), listOfProducts.end(), currentProductSet) == listOfProducts.end()){ + listOfProducts.push_back(currentProductSet); + } + } + } + } + + //Get the sum of the products of the pandigitals + for(ProductSet prod : listOfProducts){ + sumOfPandigitals += prod.getProduct(); + } + + //Stop the timer + timer.stop(); + + //Save the results + result << "There are " << listOfProducts.size() << " unique 1-9 pandigitals\nThe sum of the products of these pandigitals is " << sumOfPandigitals; + + //Throw a flag to show the problem is solved + solved = true; +} +//Reset the problem so it can be run again +void Problem32::reset(){ + Problem::reset(); + listOfProducts.clear(); + sumOfPandigitals = 0; +} +//Gets +//Returns the sum of the pandigitals +int64_t Problem32::getSumOfPandigitals(){ + //If the problem hasn't been solved throw an exception + if(!solved){ + throw Unsolved(); + } + return sumOfPandigitals; +} \ No newline at end of file diff --git a/makefile b/makefile index 729ea87..5ab3991 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++11 -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 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 67 PROBLEM_FILES = $(patsubst %,Source/libProblem%.cpp,$(PROBLEM_NUMBERS)) LIBDIR = ./lib LIBS = $(patsubst %, -lProblem%,$(PROBLEM_NUMBERS))