diff --git a/Benchmark.ts b/Benchmark.ts
new file mode 100644
index 0000000..e55b628
--- /dev/null
+++ b/Benchmark.ts
@@ -0,0 +1,186 @@
+//ProjectEulerTS/Benchmark.ts
+//Matthew Ellison
+// Created: 10-18-20
+//Modified: 10-18-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 .
+*/
+
+
+const readlineSync = require("readline-sync");
+import { Problem } from "./Problems/Problem";
+import { Stopwatch } from "../../Typescript/typescriptClasses/Stopwatch";
+import { ProblemSelection } from "./ProblemSelection";
+
+
+enum BenchmarkOptions{runSpecific = 1, runAllShort, runAll, exit, size};
+
+
+export class Benchmark{
+ private static tooLong = [];
+ //The driver function for the benchmark selection
+ public static benchmarkMenu(): void{
+ let selection: BenchmarkOptions = BenchmarkOptions.size;
+
+ Benchmark.printMenu();
+ selection = Benchmark.getMenuSelection();
+
+ switch(selection){
+ case BenchmarkOptions.runSpecific: Benchmark.runSpecific(); break;
+ case BenchmarkOptions.runAllShort: Benchmark.runAllShort(); break;
+ case BenchmarkOptions.runAll: Benchmark.runAll(); break;
+ case BenchmarkOptions.exit: break;
+ case BenchmarkOptions.size: break;
+ }
+ }
+ //Print the benchmark menu
+ private static printMenu(): void{
+ console.log("1. Run a specific problem");
+ console.log("2. Run all problems that have a reasonably short run time");
+ console.log("3. Run all problems");
+ console.log("4. Exit the menu");
+ console.log();
+ }
+ //Returns a valid menu option
+ private static getMenuSelection(): BenchmarkOptions{
+ let selection: number;
+ let sel: string = readlineSync.question("");
+ while(!Benchmark.isValidMenu(sel)){
+ console.log("That is an invalid option!\n");
+ Benchmark.printMenu();
+ selection = Benchmark.getMenuSelection();
+ }
+ selection = parseInt(sel);
+ return selection;
+ }
+ //Determines if a value is a valid menu option. Helper for getBenchmarkMenuSelection
+ private static isValidMenu(sel: string): boolean{
+ let selection: number;
+ try{
+ selection = parseInt(sel);
+ }
+ catch(error){
+ selection = -1;
+ }
+ if((selection > 0) && (selection < BenchmarkOptions.size)){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+ //Determines which problem user wants to run and runs it
+ private static runSpecific(): void{
+ //Ask which problem the user wants to run
+ let problemNumber: number = ProblemSelection.getProblemNumber();
+ //Ask how many times to run the problem
+ let timesToRun: number = Benchmark.getNumberOfTimesToRun();
+
+ //Get the problem and print its description
+ let problem: Problem = ProblemSelection.getProblem(problemNumber);
+ console.log("\n" + problemNumber + ". " + problem.getDescription());
+
+ //Run the problem the specific number of times
+ let totalTime: number = Benchmark.runProblem(problem, timesToRun);
+
+ //Print the results
+ console.log(Benchmark.getBenchmarkResults(problem, totalTime, timesToRun));
+ }
+ //Runs all problems except a few that are specific because of run length
+ private static runAllShort(): void{
+ //Ask how many times to run the problems
+ let timesToRun: number = Benchmark.getNumberOfTimesToRun();
+
+ //Run through all valid problem numbers, skipping a few that are in the tooLong list
+ for(let cnt: number = 1;cnt < ProblemSelection.PROBLEM_NUMBERS.length;++cnt){
+ let problemNumber: number = ProblemSelection.PROBLEM_NUMBERS[cnt];
+
+ //If the problem number is contained in the list of problems that take too long skip it
+ if(Benchmark.tooLong.includes(problemNumber)){
+ continue;
+ }
+
+ //Get the problem and print its description
+ let problem: Problem = ProblemSelection.getProblem(problemNumber);
+ console.log(problemNumber + ". " + problem.getDescription());
+
+ //Run each problem the specified number of times
+ let totalTime: number = Benchmark.runProblem(problem, timesToRun);
+
+ //Print the results
+ console.log(Benchmark.getBenchmarkResults(problem, totalTime, timesToRun));
+ }
+ }
+ //Runs all problems
+ private static runAll(): void{
+ //Ask how many times to run the problem
+ let timesToRun: number = Benchmark.getNumberOfTimesToRun();
+
+ //Run through all valid problem number, skipping a few that are in the tooLong list
+ for(let cnt: number = 1;cnt < ProblemSelection.PROBLEM_NUMBERS.length;++cnt){
+ let problemNumber: number = ProblemSelection.PROBLEM_NUMBERS[cnt];
+
+ //Get the problem
+ let problem: Problem = ProblemSelection.getProblem(problemNumber);
+
+ //Run each problem the specified number of times
+ console.log(problemNumber + ". " + problem.getDescription());
+ let totalTime: number = Benchmark.runProblem(problem, timesToRun);
+
+ //Print the results
+ console.log(Benchmark.getBenchmarkResults(problem, totalTime, timesToRun));
+ }
+ }
+ //Asks how many times a problem is ksupposed to run and returns the value
+ private static getNumberOfTimesToRun(): number{
+ let numberOfTimesToRun: number = 1;
+ let num: string = readlineSync.question("How many times do you want to run this problem? ");
+ try{
+ numberOfTimesToRun = parseInt(num);
+ }
+ catch(error){
+ console.log("That is an invalid number!");
+ numberOfTimesToRun = Benchmark.getNumberOfTimesToRun();
+ }
+ return numberOfTimesToRun;
+ }
+ //Runs the problem the given number of times
+ private static runProblem(problem: Problem, timesToRun: number): number{
+ let totalTime: number = 0;
+ process.stdout.write("Solving");
+ for(let cnt: number = 0;cnt < timesToRun;++cnt){
+ process.stdout.write('.');
+ //Reset the data so you are actually counting the run time an additional time
+ problem.reset();
+ //Solve the problem
+ problem.solve();
+ //Get the time dat
+ totalTime += problem.getTimer().getNano();
+ }
+ return totalTime;
+ }
+ //Prints the benchmark results of a problem
+ private static getBenchmarkResults(problem: Problem, totalTime: number, timesRun: number): string{
+ //Calculate the average run time of the problem
+ totalTime /= timesRun;
+ let timeResults: string = Stopwatch.getStr(totalTime);
+
+ //Tally the results
+ let results: string = "\n\n" + problem.getResult() + "\nIt took an average of " + timeResults + " to run this problem through " + timesRun + " iterations\n\n";
+ return results;
+ }
+}
diff --git a/ProblemSelection.ts b/ProblemSelection.ts
new file mode 100644
index 0000000..5b80ca6
--- /dev/null
+++ b/ProblemSelection.ts
@@ -0,0 +1,85 @@
+//ProjectEulerTS/ProblemSelection.ts
+//Matthew Ellison
+// Created: 10-18-20
+//Modified: 10-18-20
+//This class holds all of the functions needed to handle a problem
+//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/typescriptClasses
+/*
+ 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 .
+*/
+
+
+const readlineSync = require("readline-sync");
+import { Problem } from "./Problems/Problem";
+import { Problem1 } from "./Problems/Problem1";
+
+
+export class ProblemSelection{
+ //Holds the valid problem numbers
+ public static PROBLEM_NUMBERS = [1];
+
+ //Returns the problem corresponding to the given problem number
+ public static getProblem(problemNumber: number): Problem{
+ let problem: Problem = null;
+ switch(problemNumber){
+ case 1 : problem = new Problem1(); break;
+ }
+ return problem;
+ }
+ //Print the description of a problem
+ public static printDescription(problemNumber: number): void{
+ //Get the problem
+ let problem: Problem = ProblemSelection.getProblem(problemNumber);
+ //Print the problem's description
+ console.log(problem.getDescription() + "\n\n");
+ }
+ //Solve a problem
+ public static solveProblem(problemNumber: number): void{
+ //Get the problem
+ let problem: Problem = ProblemSelection.getProblem(problemNumber);
+ //Print the problem description
+ console.log("\n\n" + problem.getDescription());
+ //Solve the problem
+ problem.solve();
+ //Print the results
+ console.log(problem.getResult() + "\nIt took " + problem.getTime() + " to solve this problem.\n\n");
+ }
+ //Get a valid problem number from a user
+ public static getProblemNumber(): number{
+ let problemNumber: number = 0;
+ let prob = readlineSync.question("Enter a problem number: ");
+ try{
+ problemNumber = parseInt(prob);
+ }
+ catch(error){
+ problemNumber = -1;
+ }
+ while(!ProblemSelection.PROBLEM_NUMBERS.includes(problemNumber)){
+ console.log("That is an invalid problem number!");
+ problemNumber = ProblemSelection.getProblemNumber();
+ }
+ problemNumber = parseInt(prob);
+ return problemNumber;
+ }
+ //List all valid problem numbers
+ public static listProblems(): void{
+ console.log(ProblemSelection.PROBLEM_NUMBERS[1]);
+ for(let problemNumber: number = 2;problemNumber < ProblemSelection.PROBLEM_NUMBERS.length;++problemNumber){
+ console.log(", " + ProblemSelection.PROBLEM_NUMBERS[problemNumber]);
+ }
+ console.log();
+ }
+}
diff --git a/Problems/Problem.ts b/Problems/Problem.ts
index 48ae6ad..25c0902 100644
--- a/Problems/Problem.ts
+++ b/Problems/Problem.ts
@@ -37,7 +37,7 @@ export abstract class Problem{
this.solved = false;
}
//Gets
- getDescription(){
+ getDescription(): string{
return this.description;
}
//Returns the result of solving the problem
diff --git a/ProjectEuler.ts b/ProjectEuler.ts
new file mode 100644
index 0000000..2c1343d
--- /dev/null
+++ b/ProjectEuler.ts
@@ -0,0 +1,139 @@
+//ProjectEulerTS/ProjectEuler.ts
+//Matthew Ellison
+// Created: 10-18-20
+//Modified: 10-18-20
+//This is the driver function for the Java version of the ProjectEuler project
+//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/typescriptClasses
+/*
+ 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 .
+*/
+
+
+import { ProblemSelection } from "./ProblemSelection";
+import { Benchmark } from "./Benchmark";
+const readlineSync = require("readline-sync");
+
+
+//An enum to hold the possible menu selections
+enum SELECTIONS{SOLVE = 1, DESCRIPTION, LIST, BENCHMARK, EXIT, SIZE};
+
+class Driver{
+ //Drives the program
+ public static main(): void{
+ console.log("Welcome to ProjectEulerTS\nPress Enter to continue\n\n\n");
+ readlineSync.question("", {hideEchoBack: true});
+ //Holds the menu selection of the user
+ let selection: number;
+ do{
+ Driver.printMenu();
+ selection = Driver.getMenuSelection();
+
+ switch(selection){
+ case SELECTIONS.SOLVE: Driver.solveMenu(); break;
+ case SELECTIONS.DESCRIPTION: Driver.descriptionMenu(); break;
+ case SELECTIONS.LIST: ProblemSelection.listProblems(); break;
+ case SELECTIONS.BENCHMARK: Benchmark.benchmarkMenu(); break;
+ case SELECTIONS.EXIT: break;
+ case SELECTIONS.SIZE:
+ default: Driver.printErrorMessage();
+ }
+ }while(selection != SELECTIONS.EXIT);
+ }
+ //Print the menu
+ public static printMenu(): void{
+ console.log("1. Solve a problem");
+ console.log("2. Print a problem description");
+ console.log("3. List valid problem numbers");
+ console.log("4. Benchmark");
+ console.log("5. Exit");
+ console.log();
+ }
+ //Get a menu selection from the user
+ private static getMenuSelection(): SELECTIONS{
+ let selection: number;
+ let sel: string = readlineSync.question(' ');
+ while(!Driver.isValidMenu(sel)){
+ console.log("That is an invalid option!\n");
+ selection = Driver.getMenuSelection();
+ }
+ selection = parseInt(sel);
+ return selection;
+ }
+ //Make sure the value passed in is a valid menu option
+ private static isValidMenu(sel: string): boolean{
+ let selection: number;
+ try{
+ selection = parseInt(sel);
+ }
+ catch(error){
+ selection = -1;
+ }
+ if((selection > 0) && (selection < SELECTIONS.SIZE)){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+ //Print an error message
+ private static printErrorMessage(): void{
+ console.log("That is an invalid selection!");
+ }
+ //Handle what happens when a user wants to solve a problem
+ private static async solveMenu(){
+ let problemNumber: number = ProblemSelection.getProblemNumber();
+ //This selection solves all problems in order
+ if(problemNumber == 0){
+ //Solve to every valid problem number, skipping over 0
+ for(let problemLocation: number = 1;problemLocation < ProblemSelection.PROBLEM_NUMBERS.length;++problemLocation){
+ //Solve the problems
+ console.log(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 descriptionMenu(): void{
+ //Give some extra space to print the description
+ console.log("\n");
+
+ //Get the problem number
+ let problemNumber = ProblemSelection.getProblemNumber();
+
+ //If the problem number is 0 print out all the descriptions
+ if(problemNumber == 0){
+ //Print the description for every valid problem number, skipping over 0
+ for(let problemLocation: number = 1;problemLocation < ProblemSelection.PROBLEM_NUMBERS.length;++problemLocation){
+ //Print the problem's description
+ console.log(ProblemSelection.PROBLEM_NUMBERS[problemLocation] + ". ");
+ ProblemSelection.printDescription(ProblemSelection.PROBLEM_NUMBERS[problemLocation]);
+ console.log();
+ }
+ }
+ //Otherwise print out a single problem's description
+ else{
+ ProblemSelection.printDescription(problemNumber);
+ }
+ }
+}
+
+//Run the program
+Driver.main();