//ProjectEuler/Java/Problem19.java //Matthew Ellison // Created: 03-13-19 //Modified: 03-28-19 //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/JavaClasses /* Copyright (C) 2019 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 mattrixwv.Stopwatch; public class Problem19{ private static enum DAYS{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, NUMBER_OF_DAYS, ERROR}; private static final Integer START_YEAR = 1901; //The first year we are going to test private static final Integer END_YEAR = 2000; //The last year we are going to test public static void main(String[] argv){ Stopwatch timer = new Stopwatch(); Long totalSundays = 0L; //Start the timer timer.start(); //Run for all years 1901-2000 for(Integer year = START_YEAR;year <= END_YEAR;++year){ //Run for all months in the year for(Integer month = 1;month <= 12;++month){ DAYS day = getDay(month, 1, year); if(day == DAYS.ERROR){ System.out.println("There was an error with the day"); } else if(day == DAYS.SUNDAY){ ++totalSundays; } } } //Stop the timer timer.stop(); //Print the results System.out.printf("There are %d Sundays that landed on the first of the months from %d to %d\n", totalSundays, START_YEAR, END_YEAR); System.out.println("It took " + timer.getStr() + " to run this algorithms"); } //Return the day of the week that the date you pass into it is on private static DAYS getDay(Integer month, Integer day, Integer year){ //Make sure the numbers are within propper bounds if((month < 1) || (month > 12) || (day < 1) || (day > 31) || (year < 1)){ return DAYS.ERROR; } Integer numDays = 0; Integer currentYear = 1; Integer currentMonth = 1; Integer currentDay = DAYS.SATURDAY.ordinal(); --day; //Add teh currect 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){ //February if(currentMonth == 2){ if(isLeapYear(currentYear)){ numDays += 29; } else{ numDays += 28; } } //31 day months else if((currentMonth == 1) || (currentMonth == 3) || (currentMonth == 5) || (currentMonth == 7) || (currentMonth == 8) || (currentMonth == 10) || (currentMonth == 12)){ numDays += 31; } else{ numDays += 30; } ++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)){ System.out.println("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.ordinal(); DAYS typeDay = DAYS.values()[currentDay]; switch(typeDay){ case SUNDAY: return DAYS.SUNDAY; case MONDAY: return DAYS.MONDAY; case TUESDAY: return DAYS.TUESDAY; case WEDNESDAY: return DAYS.WEDNESDAY; case THURSDAY: return DAYS.THURSDAY; case FRIDAY: return DAYS.FRIDAY; case SATURDAY: return DAYS.SATURDAY; default: System.out.println("Hit default error"); return DAYS.ERROR; } } //Returns true if the year passed to it is a leap year private static Boolean isLeapYear(Integer year){ 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; } } /* Results: There are 171 Sundays that landed on the first of the months from 1901 to 2000 It took 67.638 milliseconds to run this algorithms */