From ea57a9e3e3bc6207727f0f5159869e7918cb011e Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Tue, 6 Apr 2021 11:06:37 -0400 Subject: [PATCH] Added solution to problem 19 --- ProblemSelection.ts | 4 +- Problems/Problem19.ts | 214 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 Problems/Problem19.ts diff --git a/ProblemSelection.ts b/ProblemSelection.ts index 2676014..80f7924 100644 --- a/ProblemSelection.ts +++ b/ProblemSelection.ts @@ -42,11 +42,12 @@ import { Problem15 } from "./Problems/Problem15"; import { Problem16 } from "./Problems/Problem16"; import { Problem17 } from "./Problems/Problem17"; import { Problem18 } from "./Problems/Problem18"; +import { Problem19 } from "./Problems/Problem19"; export class ProblemSelection{ //Holds the valid problem numbers - public static PROBLEM_NUMBERS: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]; + public static PROBLEM_NUMBERS: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]; //Returns the problem corresponding to the given problem number public static getProblem(problemNumber: number): Problem{ @@ -70,6 +71,7 @@ export class ProblemSelection{ case 16: problem = new Problem16(); break; case 17: problem = new Problem17(); break; case 18: problem = new Problem18(); break; + case 19: problem = new Problem19(); break; } return problem; } diff --git a/Problems/Problem19.ts b/Problems/Problem19.ts new file mode 100644 index 0000000..0662550 --- /dev/null +++ b/Problems/Problem19.ts @@ -0,0 +1,214 @@ +//ProjectEulerTS/Problems/Problem18.ts +//Matthew Ellison +// Created: 04-06-21 +//Modified: 04-06-21 +//How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)? +/* +You are given the following information, but you may prefer to do some research for yourself. +1 Jan 1900 was a Monday. +Thirty days has September, +April, June and November. +All the rest have thirty-one, +Saving February alone, +Which has twenty-eight, rain or shine. +And on leap years, twenty-nine. +A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400. +*/ +//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/typescriptClasses +/* + 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 . +*/ + + +import { Unsolved } from "../Unsolved"; +import { Problem } from "./Problem"; + + +//An easier way to signal day of the week +enum DAYS {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FIRDAY, SATURDAY, NUMBER_OF_DAYS, ERROR}; + + +export class Problem19 extends Problem{ + //Variables + //Static variables + private static START_YEAR: number = 1901; //The first year we are going to test + private static END_YEAR: number = 2000; //The last year we are going to test + //Instance variables + private totalSundays: number; //Keep track of the number of sundays + + //Functions + //Constructor + public constructor(){ + super(`How many Sundays fell on the first of the month during the twentieth century (1 Jan ${Problem19.START_YEAR} to 31 Dec ${Problem19.END_YEAR})?`); + this.totalSundays = 0; + } + //Operational functions + //Solve the problem + public solve(): void{ + //If the problem has already been solved do nothing and end the function + if(this.solved){ + return; + } + + //Start the timer + this.timer.start(); + + //Run for all years 1901-2000 + for(let year = Problem19.START_YEAR;year <= Problem19.END_YEAR;++year){ + //Run for all months in the year + for(let month = 1;month <= 12;++month){ + let day: DAYS = this.getDay(month, 1, year); + if(day == DAYS.ERROR){ + console.log("There was an error with the day"); + } + else if(day == DAYS.SUNDAY){ + ++this.totalSundays; + } + } + } + + //Stop the timer + this.timer.stop(); + + //Throw a flag to show the problem is solved + this.solved = true; + } + //Return the day of the week that the data you pass into it is on + private getDay(month: number, day: number, year: number): DAYS{ + //Make sure the numbers are within propper bounds + if((month < 1) || (month > 12) || (day < 1) || (day > 31) || (year < 1)){ + return DAYS.ERROR; + } + let numDays: number = 0; + let currentYear: number = 1; + let currentMonth: number = 1; + let currentDay: number = DAYS.SATURDAY; + --day; + + //Add the correct number of days for every year + while(currentYear < year){ + if(this.isLeapYear(currentYear)){ + numDays += 366; + } + else{ + numDays += 365; + } + ++currentYear; + } + //Add the correct number of days for every month + while(currentMonth < month){ + switch(currentMonth){ + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: numDays += 31; break; + case 4: + case 6: + case 9: + case 11: numDays += 30; break; + case 2: + if(this.isLeapYear(currentYear)){ + numDays += 29; + } + else{ + numDays += 28; + } + break; + } + ++currentMonth; + } + //Account for the weird year of 1752 + if(year > 1752){ + numDays -= 11; + } + else if(year == 1752){ + if(month > 9){ + numDays -= 11; + } + else if(month == 9){ + if(day >= 14){ + numDays -= 11; + } + else if((day > 2) && (day < 14)){ + console.log("Hit 1752 error"); + return DAYS.ERROR; + } + } + } + //Add the correct number of days for every day + numDays += day; + + currentDay += numDays; + currentDay = currentDay % DAYS.NUMBER_OF_DAYS; + switch(currentDay){ + case DAYS.SUNDAY: return DAYS.SUNDAY; + case DAYS.MONDAY: return DAYS.MONDAY; + case DAYS.TUESDAY: return DAYS.TUESDAY; + case DAYS.WEDNESDAY: return DAYS.WEDNESDAY; + case DAYS.THURSDAY: return DAYS.THURSDAY; + case DAYS.FIRDAY: return DAYS.FIRDAY; + case DAYS.SATURDAY: return DAYS.SATURDAY; + default: console.log("Hit default error"); return DAYS.ERROR; + } + } + //Returns true if the year passed to it is a leap year + private isLeapYear(year: number): boolean{ + if(year < 1){ + return false; + } + else if((year % 100) == 0){ + //This rule only applies at and after 1800 + if(year <= 1700){ + return true; + } + else if((year % 400) == 0){ + return true; + } + } + else if((year % 4) == 0){ + return true; + } + return false; + } + //Reset the problem so it can be run again + public reset(): void{ + super.reset(); + this.totalSundays = 0; + } + //Gets + //Returns the result of solving the problem + public getResult(): string{ + if(!this.solved){ + throw new Unsolved(); + } + return `There are ${this.totalSundays} Sundays that landed on the first of the months from ${Problem19.START_YEAR} to ${Problem19.END_YEAR}`; + } + //Returns the total sundays that were asked for + public getTotalSundays(): number{ + if(!this.solved){ + throw new Unsolved(); + } + return this.totalSundays; + } +} + +/* Results: +There are 171 Sundays that landed on the first of the months from 1901 to 2000 +It took an average of 4.314 milliseconds to run this problem through 100 iterations +*/