Added Driver program and Problem 2

This commit is contained in:
2020-08-23 02:58:49 -04:00
parent 4eb8c72ddd
commit 1cb9df9ddc
12 changed files with 599 additions and 28 deletions

7
.gitignore vendored
View File

@@ -1,2 +1,7 @@
#IDE files
.vs
.vscode
#Executables
*.exe
ProjectEulerCS/bin
ProjectEulerCS/obj

25
ProjectEulerCS.sln Normal file
View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30413.136
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectEulerCS", "ProjectEulerCS\ProjectEulerCS.csproj", "{E671E64D-6B7F-4952-8618-828225AAB294}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E671E64D-6B7F-4952-8618-828225AAB294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E671E64D-6B7F-4952-8618-828225AAB294}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E671E64D-6B7F-4952-8618-828225AAB294}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E671E64D-6B7F-4952-8618-828225AAB294}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B50E41B6-664C-4441-AF9F-B9526CCA0A72}
EndGlobalSection
EndGlobal

191
ProjectEulerCS/Benchmark.cs Normal file
View File

@@ -0,0 +1,191 @@
//ProjectEuler/ProjectEulerCS/src/ProblemSelection.cs
//Matthew Ellison
// Created: 08-22-20
//Modified: 08-22-20
//This runs the benchmark functions for the Java version of the ProjectEuler project
/*
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 <https://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace ProjectEulerCS{
public class Benchmark{
private enum BenchmarkOptions { runSpecific = 1, runAllShort, runAll, exit, size };
private static readonly List<int> tooLong = new List<int>();
//The driver function for the benchmark selection
public static void benchmarkMenu(){
BenchmarkOptions selection = BenchmarkOptions.size;
printMenu();
selection = getMenuSelection();
switch(selection){
case BenchmarkOptions.runSpecific: runSpecific(); break;
case BenchmarkOptions.runAllShort: runAllShort(); break;
case BenchmarkOptions.runAll: runAll(); break;
case BenchmarkOptions.exit: break;
case BenchmarkOptions.size: break;
}
}
//Print the benchmark menu
private static void printMenu(){
System.Console.WriteLine("1. Run a specific problem");
System.Console.WriteLine("2. Run all problems that have a reasonably short run time");
System.Console.WriteLine("3. Run all problems");
System.Console.WriteLine("4. Exit the menu");
System.Console.WriteLine();
}
//Returns a valid menu option
private static BenchmarkOptions getMenuSelection(){
string selectionString = System.Console.ReadLine();
int selection = System.Convert.ToInt32(selectionString);
while(!isValidMenu(selection)){
System.Console.WriteLine("That is an invalid option!\nPress Enter to continue");
printMenu();
selectionString = System.Console.ReadLine();
selection = System.Convert.ToInt32(selectionString);
}
return getSelection(selection);
}
//Determines if a value is a valid menu option. Helper for getBenchmarMenuSeleciton
private static bool isValidMenu(int selection){
if((selection >= (int)BenchmarkOptions.runSpecific) && (selection < (int)BenchmarkOptions.size)){
return true;
}
else{
return false;
}
}
//A helper function for getMenuSelection that turns an integer to a BenchmarkOptions
private static BenchmarkOptions getSelection(int selection){
BenchmarkOptions sel = BenchmarkOptions.size;
switch(selection){
case 1: sel = BenchmarkOptions.runSpecific; break;
case 2: sel = BenchmarkOptions.runAllShort; break;
case 3: sel = BenchmarkOptions.runAll; break;
case 4: sel = BenchmarkOptions.exit; break;
default: sel = BenchmarkOptions.size; break;
}
return sel;
}
//Determines which problem user wants to run and runs it
private static void runSpecific(){
//Ask which problem the user wants to run
int problemNumber = ProblemSelection.getProblemNumber();
//Ask how many times to run the problem
int timesToRun = getNumberOfTimesToRun();
//Get the problem and print its description
Problem problem = ProblemSelection.getProblem(problemNumber);
System.Console.WriteLine(problemNumber + ". " + problem.description);
//Run the problem the specific number of times
decimal totalTime = runProblem(problem, timesToRun);
//Print the results
System.Console.WriteLine(getBenchmarkResults(problem, totalTime, timesToRun));
}
//Runs all problems except a few that are specified because of run length
private static void runAllShort(){
//Ask how many times to run the problems
int timesToRun = getNumberOfTimesToRun();
//Run through all valid problem numbers, skipping a few that are in the tooLong list
for(int cnt = 1; cnt < ProblemSelection.PROBLEM_NUMBERS.Count; ++cnt){
int problemNumber = ProblemSelection.PROBLEM_NUMBERS[cnt];
//If the problem number is contained in the list of problems that take too long skip it
if(tooLong.IndexOf(problemNumber) != -1){
continue;
}
//Get the problem and print its description
Problem problem = ProblemSelection.getProblem(problemNumber);
System.Console.WriteLine(problemNumber + ". " + problem.description);
//Run each problem the specified number of times
decimal totalTime = runProblem(problem, timesToRun);
//Print the results
System.Console.WriteLine(getBenchmarkResults(problem, totalTime, timesToRun));
}
}
//Runs all problems
private static void runAll(){
//Ask how many times to run the problem
int timesToRun = getNumberOfTimesToRun();
//Run through all valid problem numbers, skipping a few that are in the tooLong list
for(int cnt = 1; cnt < ProblemSelection.PROBLEM_NUMBERS.Count; ++cnt){
int problemNumber = ProblemSelection.PROBLEM_NUMBERS[cnt];
//Get the problem
Problem problem = ProblemSelection.getProblem(problemNumber);
//Run each problem the specified number of times
System.Console.WriteLine(problemNumber + ". " + problem.description);
decimal totalTime = runProblem(problem, timesToRun);
//Print the results
System.Console.WriteLine(getBenchmarkResults(problem, totalTime, timesToRun));
}
}
//Asks how many times a problem is supposed to run and returns the value
private static int getNumberOfTimesToRun(){
int numOfTimesToRun = 1;
System.Console.Write("How many times do you want to run this problem? ");
string numOfTimesToRunString = System.Console.ReadLine();
numOfTimesToRun = System.Convert.ToInt32(numOfTimesToRunString);
while(numOfTimesToRun < 1){
System.Console.WriteLine("That is an invalid number!");
System.Console.Write("How many times do you want to run this problem? ");
numOfTimesToRunString = System.Console.ReadLine();
numOfTimesToRun = System.Convert.ToInt32(numOfTimesToRunString);
}
return numOfTimesToRun;
}
//Runs the problem the given number of times
private static decimal runProblem(Problem problem, int timesToRun){
decimal totalTime = 0;
System.Console.Write("Solving");
for(int cnt = 0; cnt < timesToRun; ++cnt){
System.Console.Write('.');
//Reset the data so you care actually counting the run time an additional time
problem.reset();
//Solve the problem
problem.solve();
//Get the time data
totalTime += problem.timer.getNano();
}
return totalTime;
}
//Prints the benchmark results of a problem
private static string getBenchmarkResults(Problem problem, decimal totalTime, int timesRun){
//Calculate the average run time of the problem
totalTime /= timesRun;
string timeResults = mee.Stopwatch.getStr(totalTime);
//Tally the results
string results = "\n\n" + problem.result + "\nIt took an average of " + timeResults + " to run this problem through " + timesRun + " iterations\n\n";
return results;
}
}
}

View File

@@ -0,0 +1,84 @@
//ProjectEuler/ProjectEulerCS/src/ProblemSelection.cs
//Matthew Ellison
// Created: 08-21-20
//Modified: 08-21-20
//This class holds all of the functions needed to handle a problem
/*
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 <https://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace ProjectEulerCS{
public class ProblemSelection{
//Holds the valid problem numbers
private static readonly List<int> _PROBLEM_NUMBERS = new List<int>() { 0, 1, 2 };
public static System.Collections.Generic.List<int> PROBLEM_NUMBERS{
get { return _PROBLEM_NUMBERS; }
}
//Returns the problem corresponding to the given problem number
public static Problem getProblem(int problemNumber){
Problem problem = null;
switch(problemNumber){
case 1: problem = new Problem1(); break;
case 2: problem = new Problem2(); break;
}
return problem;
}
//Print the description of a problem
public static void printDescription(int problemNumber){
//Get the problem
Problem problem = getProblem(problemNumber);
//Print the problem's description
System.Console.WriteLine(problem.description);
}
//Solve a problem
public static void solveProblem(int problemNumber){
//Get the problem
Problem problem = getProblem(problemNumber);
//Print the problem description
System.Console.WriteLine(problem.description);
//Solve the problem
problem.solve();
//Print the results
System.Console.WriteLine(problem.result + "\nIt took " + problem.time + " to solve this problem.\n\n");
}
//Get a valid problem number from a user
public static int getProblemNumber(){
int problemNumber = 0;
System.Console.Write("Enter a problem number: ");
string problemNumberString = System.Console.ReadLine();
problemNumber = System.Convert.ToInt32(problemNumberString);
while(_PROBLEM_NUMBERS.IndexOf(problemNumber) == -1){
System.Console.Write("That is an invalid problem number!\nEnter a problem number: ");
problemNumberString = System.Console.ReadLine();
problemNumber = System.Convert.ToInt32(problemNumberString);
}
return problemNumber;
}
//List all valid problem numbers
public static void listProblems(){
System.Console.Write(_PROBLEM_NUMBERS[1]);
for(int problemNumber = 2; problemNumber < _PROBLEM_NUMBERS.Count; ++problemNumber){
System.Console.Write(", " + _PROBLEM_NUMBERS[problemNumber]);
}
System.Console.WriteLine();
}
}
}

View File

@@ -1,24 +1,32 @@
//ProjectEuler/ProjectEulerCS/src/Problems/Problem.cs
//ProjectEuler/ProjectEulerCS/src/Problems/Problem.cs
//Matthew Ellison
// Created: 08-14-20
//Modified: 08-14-20
//This is the base class for the rest of the problems
namespace mee{
namespace ProjectEulerCS{
public abstract class Problem{
//Variables
//Instance variables
//protected const Stopwatch timer = new Stopwatch(); //To time how long it takes to run the algorithm
protected string _result = null; //Holds the results of the problem
public string result{
get{ return _result; }
get { return _result; }
}
protected readonly string _description; //Holds the description of the problem
protected readonly string _description; //Holds the description of the problem
public string description{
get{ return _description; }
get { return _description; }
}
protected bool solved; //Shows whether the problem has already been solved
protected bool solved; //Shows whether the problem has already been solved
protected mee.Stopwatch _timer = new mee.Stopwatch();
public mee.Stopwatch timer{
get { return _timer; }
}
public string time{
get { return _timer.getStr(); }
}
//Constructor
public Problem(string description){

View File

@@ -1,4 +1,4 @@
//ProjectEuler/ProjectEulerCS/src/Problems/Problem1.cs
//ProjectEuler/ProjectEulerCS/src/Problems/Problem1.cs
//Matthew Ellison
// Created: 08-14-20
//Modified: 08-14-20
@@ -21,14 +21,14 @@
*/
namespace mee{
namespace ProjectEulerCS{
public class Problem1 : Problem{
//Variables
private const int TOP_NUM = 999; //THe largest number to tbe checked
//Instance variables
private const int TOP_NUM = 999; //The largest number to tbe checked
//Instance variables
private int fullSum; //The sum of all the numbers
public int sum{
get{ return fullSum; }
get { return fullSum; }
}
//Functions
@@ -40,32 +40,31 @@ namespace mee{
//Solve the problem
public override void solve(){
//If the problem has already been solved do nothing and end the function
if(solved){
if (solved){
return;
}
//Start the timer
//timer.start();
timer.start();
//Check every number < 1000 to see if it is a multiple of 3 or 5. If it is add it to the running sum
for(int cnt = 1;cnt <= TOP_NUM;++cnt){
if((cnt %3) == 0){
for (int cnt = 1; cnt <= TOP_NUM; ++cnt){
if ((cnt % 3) == 0){
fullSum += cnt;
}
else if((cnt % 5) == 0){
else if ((cnt % 5) == 0){
fullSum += cnt;
}
}
//Stop the timer
//timer.stop();
timer.stop();
//Thow a flag to show the problem is solved
solved = true;
//Save the results
_result = "The sum of all numbers < " + (TOP_NUM + 1) + " is " + fullSum;
System.Console.WriteLine(result);
}
//Reset the problem so it can be run again
@@ -74,4 +73,9 @@ namespace mee{
fullSum = 0;
}
}
}
}
/* Results:
The sum of all numbers < 1000 is 233168
It took an average of 73.837 microseconds to run this problem through 100 iterations
*/

View File

@@ -0,0 +1,76 @@
//ProjectEuler/ProjectEulerCS/src/Problems/Problem2.cs
//Matthew Ellison
// Created: 08-23-20
//Modified: 08-23-20
//What is the sum of all the multiples of 3 or 5 that are less than 1000
/*
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 <https://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace ProjectEulerCS{
public class Problem2 : Problem{
//Variables
//Static variables
private const int TOP_NUM = 4000000 - 1; //The largest number that will be checked as a fibonacci number
//Instance variables
private int fullSum; //Holds the sum of all the numbers
//Functions
//Constructor
public Problem2() : base("What is the sum of the even Fibonacci numbers less than 4,000,000?"){
fullSum = 0;
}
//Operational functions
//Solve the problem
public override void solve(){
//If the problem has already been solved do nothing and end the function
if(solved){
return;
}
//Start the timer
timer.start();
//Get a list of all fibonacci numbers < 4,000,000
List<int> fibNums = mee.Algorithms.getAllFib(TOP_NUM);
//Step through every element in the list checkint if it is even
foreach(int num in fibNums){
//If the number is even add it to the running tally
if((num % 2) == 0){
fullSum += num;
}
}
//Stop the timer
timer.stop();
//Throw a flag to show the problem is solved
solved = true;
//Save the results
_result = "The sum of all even fibonacci numbers <= " + TOP_NUM + " is " + fullSum;
}
public override void reset(){
base.reset();
fullSum = 0;
}
}
}

View File

@@ -0,0 +1,138 @@
//ProjectEuler/ProjectEulerCS/src/ProblemSelection.cs
//Matthew Ellison
// Created: 08-21-20
//Modified: 08-21-20
//This is the driver function for the C# version of the ProjectEuler project
/*
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 <https://www.gnu.org/licenses/>.
*/
namespace ProjectEulerCS{
public class ProjectEuler{
//An enum to hold the possible menu selections
private enum SELECTIONS { SOLVE = 1, DESCRIPTION, LIST, BENCHMARK, EXIT, SIZE };
//Drives the program
public static void Main(string[] args){
SELECTIONS selection = SELECTIONS.SIZE;
do{
//Print the menu and prompt the user to select an action
printMenu();
selection = getMenuSelection();
switch(selection){
case SELECTIONS.SOLVE: solveMenu(); break;
case SELECTIONS.DESCRIPTION: descriptionMenu(); break;
case SELECTIONS.LIST: ProblemSelection.listProblems(); break;
case SELECTIONS.BENCHMARK: Benchmark.benchmarkMenu(); break;
case SELECTIONS.EXIT: break;
case SELECTIONS.SIZE:
default: printErrorMessage(); break;
}
}while(!selection.Equals(SELECTIONS.EXIT));
}
//Print the menu
private static void printMenu(){
System.Console.WriteLine("1. Solve a problem");
System.Console.WriteLine("2. Print a problem description");
System.Console.WriteLine("3. List valid problem numbers");
System.Console.WriteLine("4. Benchmark");
System.Console.WriteLine("5. Exit");
System.Console.WriteLine();
}
//Get a menu selection from the user
private static SELECTIONS getMenuSelection(){
string selectionString = System.Console.ReadLine();
int selection = System.Convert.ToInt32(selectionString);
while(!isValidMenu(selection)){
System.Console.WriteLine("that is an invalid option!\nPress Enter to continue");
printMenu();
selectionString = System.Console.ReadLine();
selection = System.Convert.ToInt32(selectionString);
}
return getSelection(selection);
}
//Make sure the value passed in is a valid menu option
private static bool isValidMenu(int selection){
if((selection >= (int)SELECTIONS.SOLVE) && (selection < (int)SELECTIONS.SIZE)){
return true;
}
else{
return false;
}
}
//Turns an integer passed to it into a SELECTION enum
private static SELECTIONS getSelection(int selection){
SELECTIONS sel = SELECTIONS.SIZE;
switch(selection){
case 1: sel = SELECTIONS.SOLVE; break;
case 2: sel = SELECTIONS.DESCRIPTION; break;
case 3: sel = SELECTIONS.LIST; break;
case 4: sel = SELECTIONS.BENCHMARK; break;
case 5: sel = SELECTIONS.EXIT; break;
default: sel = SELECTIONS.SIZE; break;
}
return sel;
}
//Print an error message
private static void printErrorMessage(){
System.Console.WriteLine("That is an invalid selection!");
}
//Handle what happens when a user wants to solve a problem
private static void solveMenu(){
int problemNumber = ProblemSelection.getProblemNumber();
//This selection solves all problems in order
if(problemNumber == 0){
//Solve to every valid problem number, skipping over 0
for(int problemLocation = 1; problemLocation < ProblemSelection.PROBLEM_NUMBERS.Count; ++problemLocation){
//Solve the problems
System.Console.Write(ProblemSelection.PROBLEM_NUMBERS[problemLocation] + ". ");
ProblemSelection.solveProblem(ProblemSelection.PROBLEM_NUMBERS[problemLocation]);
}
}
//This is if a single problem number was chosen
else{
//Solve the problem
ProblemSelection.solveProblem(problemNumber);
}
}
//Handle what happens when a user wants to see the description of a problem
private static void descriptionMenu(){
//Give some extra space to print the description
System.Console.WriteLine("\n");
//Get the problem number
int problemNumber = ProblemSelection.getProblemNumber();
//If the problem number is 0 print out all the descriptions
if(problemNumber == 0){
//Print description for every valid problem number, skipping over 0
for(int problemLocation = 1; problemLocation < ProblemSelection.PROBLEM_NUMBERS.Count; ++problemLocation){
//Print the problem's descrfiption
System.Console.Write(ProblemSelection.PROBLEM_NUMBERS[problemLocation] + ". ");
ProblemSelection.printDescription(ProblemSelection.PROBLEM_NUMBERS[problemLocation]);
System.Console.WriteLine();
}
}
//Otherwise print out a single problem's description
else{
ProblemSelection.printDescription(problemNumber);
}
}
}
}

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="CSClasses">
<HintPath>..\..\..\C#\CSClasses\CSClasses\bin\Release\netstandard2.0\CSClasses.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,34 @@
//ProjectEuler/ProjectEulerCS/src/Unsolved.cs
//Matthew Ellison
// Created: 08-21-20
//Modified: 08-21-20
//This is an exception that is thrown by the problem classes
/*
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 <https://www.gnu.org/licenses/>.
*/
using System;
namespace ProjectEulerCS{
[Serializable]
public class Unsolved : Exception{
public Unsolved(){
}
public Unsolved(string str) : base(str){
}
}
}

View File

View File

@@ -1,8 +0,0 @@
namespace mee{
public class ProjectEuler{
public static void Main(string[] args){
Problem1 prob = new Problem1();
prob.solve();
}
}
}