From 27b7b2e518c7e65e277a359b652e9e1ae40a1f05 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Wed, 26 Aug 2020 19:20:56 -0400 Subject: [PATCH] Added solution to problem 19 --- ProjectEulerCS/ProblemSelection.cs | 4 +- ProjectEulerCS/Problems/Problem19.cs | 202 +++++++++++++++++++++++++++ 2 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 ProjectEulerCS/Problems/Problem19.cs diff --git a/ProjectEulerCS/ProblemSelection.cs b/ProjectEulerCS/ProblemSelection.cs index 0c38aee..9d43373 100644 --- a/ProjectEulerCS/ProblemSelection.cs +++ b/ProjectEulerCS/ProblemSelection.cs @@ -31,7 +31,8 @@ namespace ProjectEulerCS{ //Holds the valid problem numbers private static readonly List _PROBLEM_NUMBERS = new List() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 67}; + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 67}; public static System.Collections.Generic.List PROBLEM_NUMBERS{ get { return _PROBLEM_NUMBERS; } } @@ -58,6 +59,7 @@ namespace ProjectEulerCS{ case 16: problem = new Problem16(); break; case 17: problem = new Problem17(); break; case 18: problem = new Problem18(); break; + case 19: problem = new Problem19(); break; case 67: problem = new Problem67(); break; } return problem; diff --git a/ProjectEulerCS/Problems/Problem19.cs b/ProjectEulerCS/Problems/Problem19.cs new file mode 100644 index 0000000..30c5851 --- /dev/null +++ b/ProjectEulerCS/Problems/Problem19.cs @@ -0,0 +1,202 @@ +//ProjectEuler/ProjectEulerCS/src/Problems/Problem19.cs +//Matthew Ellison +// Created: 08-26-20 +//Modified: 08-26-20 +//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/CSClasses +/* + 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 . +*/ + + +using System; + + +namespace ProjectEulerCS.Problems{ + public class Problem19 : Problem{ + //Variables + //Static variables + //An easier way to signal day of the week + private enum DAYS{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, NUMBER_OF_DAYS, ERROR} + private const int START_YEAR = 1901; //The first year we are going to test + private const int END_YEAR = 2000; //The last year we are going to test + //Instance + private long totalSundays; //Keep track of the number of sundays + + //Functions + //Constructor + public Problem19() : base("How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?"){ + totalSundays = 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(); + + //Run for all years 1901-2000 + for(int year = START_YEAR;year <= END_YEAR;++year){ + //Run for all months in the year + for(int month = 1;month <= 12;++month){ + DAYS day = GetDay(month, 1, year); + if(day == DAYS.ERROR){ + throw new Exception("There was an error with the day"); + } + else if(day == DAYS.SUNDAY){ + ++totalSundays; + } + } + } + + //Stop the timer + _timer.Stop(); + + //Throw a flag to show the problem is solved + solved = true; + + _result = "There are " + totalSundays + " Sundays that landed on the first of the months from " + START_YEAR + " to " + END_YEAR; + } + //Return the day of the week that the date you pass into it is on + private DAYS GetDay(int month, int day, int year){ + //Make sure the numbers are within propper bounds + if((month < 1) || (month > 12) || (day < 1) || (day > 31) || (year < 1)){ + return DAYS.ERROR; + } + int numDays = 0; + int currentYear = 1; + int currentMonth = 1; + int currentDay = (int)DAYS.SATURDAY; + --day; + + //Add the correct number of days for every year + while(currentYear < year){ + if(IsLeapYear(currentYear)){ + numDays += 366; + } + else{ + numDays += 365; + } + ++currentYear; + } + //Add the correct number of days for every month + while(currentMonth < month){ + //31 day months + 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(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; + } + //Days 3-13 were skipped that year + else if((day >2) && (day < 14)){ + throw new Exception("Hit 1752 error"); + } + } + } + //Add the correct number of days for every day + numDays += day; + + currentDay += numDays; + currentDay %= (int)DAYS.NUMBER_OF_DAYS; + + return currentDay switch{ + (int)DAYS.SUNDAY => DAYS.SUNDAY, + (int)DAYS.MONDAY => DAYS.MONDAY, + (int)DAYS.TUESDAY => DAYS.TUESDAY, + (int)DAYS.WEDNESDAY => DAYS.WEDNESDAY, + (int)DAYS.THURSDAY => DAYS.THURSDAY, + (int)DAYS.FRIDAY => DAYS.FRIDAY, + (int)DAYS.SATURDAY => DAYS.SATURDAY, + (int)DAYS.ERROR => DAYS.ERROR, + _ => DAYS.ERROR, + }; + } + //Returns true if the year passed to it is a leap year + private bool IsLeapYear(int year){ + if(year < 1){ + return false; + } + else if((year % 100) == 0){ + //This rule only applies at or 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 override void Reset(){ + base.Reset(); + totalSundays = 0; + } + } +} + +/* Results: +There are 171 Sundays that landed on the first of the months from 1901 to 2000 +It took an average of 6.001 milliseconds to run this problem through 100 iterations +*/