Files
ProjectEulerCPP/benchmark.cpp
2020-07-08 20:56:18 -04:00

168 lines
5.5 KiB
C++

//ProjectEulerCPP/benchmark.cpp
//Mattrixwv
// Created: 07-08-20
//Modified: 07-08-20
//This is a program that runs a problem several times to get the average time it takes to run
#include <iostream>
#include <vector>
#include "ProblemSelection.hpp"
void printMenu(); //Prints the menu to the screen
int getMenuSelection(); //Returns a valid menu option
bool isValidMenu(int selection); //Determines if a value is a valid menu option. Helper for getMenuSelection
void runSpecific(); //Determines which problem user wants to run and runs it
void runAllShort(); //Runs all problems except a few that are specified because of run length
void runAll(); //Runs all problems
unsigned int getNumberOfTimesToRun(); //Asks how many times a problem is supposed to run and returns the value
enum MENU_OPTIONS {RUN_SPECIFIC = 1, RUN_ALL_SHORT, RUN_ALL, EXIT, SIZE};
std::vector<unsigned int> tooLong = {15};
int main(){
int selection = 0;
do{
printMenu();
selection = getMenuSelection();
switch(selection){
case RUN_SPECIFIC: runSpecific(); break;
case RUN_ALL_SHORT: runAllShort(); break;
case RUN_ALL: runAll(); break;
case EXIT: break;
}
}while(selection != EXIT);
return 0;
}
void printMenu(){
std::cout << "1. Run a specific problem\n"
<< "2. Run all problems that have a reasonably short run time\n"
<< "3. Run all problems\n"
<< "4. Exit the program" << std::endl;
}
int getMenuSelection(){
int selection = 0;
std::cin >> selection;
while(std::cin.fail() || !isValidMenu(selection)){
std::cout << "That is an invalid option!\nPress Enter to continue" << std::endl;
std::cin.clear();
std::cin.get();
printMenu();
std::cin >> selection;
}
return selection;
}
bool isValidMenu(int selection){
if((selection > 0) && (selection < MENU_OPTIONS::SIZE)){
return true;
}
else{
return false;
}
}
void runSpecific(){
double totalTime = 0;
//Ask which problem the user wants to run
unsigned int problemNumber = getProblemNumber();
//Ask how many times to run the problem
unsigned int timesToRun = getNumberOfTimesToRun();
//Get the problem
Problem* problem = getProblem(problemNumber);
//Run the problem the specific number of times
std::cout << "Solving";
for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
//Reset the data so you are actually counting the run time a second time
problem->reset();
(std::cout << '.').flush();
//Solve the problem
problem->solve();
//Get the time data
totalTime += problem->getTimer().getNano();
}
//Calculate the average run time
totalTime /= timesToRun;
std::string timeResults = mee::Stopwatch::getStr(totalTime);
//Print the results
std::cout << "\n\n" << problem->getString();
std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
}
void runAllShort(){
//Ask how many times to run the problem
unsigned int timesToRun = getNumberOfTimesToRun();
//Run through all valid problem numbers, skipping a few that are in the tooLong vector
for(unsigned int cnt = 1;cnt < PROBLEM_NUMBERS.size();++cnt){
unsigned int problemNumber = PROBLEM_NUMBERS[cnt];
double totalTime = 0;
//If the problem number is contained the list of problems that take too long skip it
if(mee::isFound(tooLong, problemNumber)){
continue;
}
//Get the problem
Problem* problem = getProblem(problemNumber);
//Run each problem the specified number of times
std::cout << "Solving";
for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
//Reset the data so you are actually counting the run time a second time
problem->reset();
(std::cout << '.').flush();
//Solve the problem
problem->solve();
//Get the time data
totalTime += (problem->getTimer()).getNano();
}
//Calculate the average run time of the problem
totalTime /= timesToRun;
std::string timeResults = mee::Stopwatch::getStr(totalTime);
//Print the results
std::cout << "\n\n" << problem->getString();
std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
}
}
void runAll(){
//Ask how many times to run the problem
unsigned int timesToRun = getNumberOfTimesToRun();
//Run through all valid problem numbers, skipping a few that are in the tooLong vector
for(unsigned int cnt = 1;cnt < PROBLEM_NUMBERS.size();++cnt){
unsigned int problemNumber = PROBLEM_NUMBERS[cnt];
double totalTime = 0;
//Get the problem
Problem* problem = getProblem(problemNumber);
//Run each problem the specified number of times
std::cout << "Solving";
for(unsigned int cnt = 0;cnt < timesToRun;++cnt){
//Reset the data so you are actually counting the run time a second time
problem->reset();
(std::cout << '.').flush();
//Solve the problem
problem->solve();
//Get the time data
totalTime += (problem->getTimer()).getNano();
}
//Calculate the average run time of the problem
totalTime /= timesToRun;
std::string timeResults = mee::Stopwatch::getStr(totalTime);
//Print the results
std::cout << "\n\n" << problem->getString();
std::cout << "\nIt took an average of " << timeResults << " to run this problem over " << timesToRun << " iterations\n\n" << std::endl;
}
}
unsigned int getNumberOfTimesToRun(){
unsigned int numOfTimesToRun = 1;
std::cout << "How many times do you want to run this problem? ";
std::cin >> numOfTimesToRun;
while((std::cin.fail()) || (numOfTimesToRun < 1)){
std::cout << "That is an invalid number!\nHow many times do you want to run this problem? ";
std::cin.clear();
std::cin >> numOfTimesToRun;
}
return numOfTimesToRun;
}