From 92030866e90abdadf80190fa0c203d4e64889dc5 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Wed, 17 Jun 2020 11:22:14 -0400 Subject: [PATCH] Added solution to problem 19 --- src/Problems.rs | 3 +- src/Problems/Problem19.rs | 197 ++++++++++++++++++++++++++++++++++++++ src/main.rs | 11 ++- 3 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 src/Problems/Problem19.rs diff --git a/src/Problems.rs b/src/Problems.rs index b3024eb..06fd858 100644 --- a/src/Problems.rs +++ b/src/Problems.rs @@ -1,7 +1,7 @@ //ProjectEulerRust/src/Problems.rs //Matthew Ellison // Created: 06-11-20 -//Modified: 06-15-20 +//Modified: 06-17-20 //This file just forwards all the problem modules //Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/RustClasses /* @@ -41,3 +41,4 @@ pub mod Problem15; pub mod Problem16; pub mod Problem17; pub mod Problem18; +pub mod Problem19; diff --git a/src/Problems/Problem19.rs b/src/Problems/Problem19.rs new file mode 100644 index 0000000..15e8808 --- /dev/null +++ b/src/Problems/Problem19.rs @@ -0,0 +1,197 @@ +//ProjectEulerRust/src/Problems/Problems19.rs +//Matthew Ellison +// Created: 06-17-20 +//Modified: 06-17-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/RustClasses +/* + 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 . +*/ + + +extern crate myClasses; +use crate::Problems::Answer::Answer; + +pub fn getDescription() -> String{ + "How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?".to_string() +} + +#[allow(non_camel_case_types)] +#[derive(PartialEq)] +enum DAYS{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THRUSDAY, FRIDAY, SATURDAY, NUMBER_OF_DAYS, ERROR} + +pub fn solve() -> Answer{ + //The first year we are going to test + let START_YEAR = 1901; + //The last year we are going to test + let END_YEAR = 2000; + //The total number of sundays + let mut totalSundays = 0; + + //Start the timer + let mut timer = myClasses::Stopwatch::Stopwatch::new(); + timer.start(); + + //Run for all years 1901-2000 + for year in START_YEAR..=END_YEAR{ + //Run for all months in the year + for month in 1..=12{ + let day = getDay(month, 1, year); + if(day == DAYS::ERROR){ + println!("There was an error with the day"); + } + else if(day == DAYS::SUNDAY){ + totalSundays += 1; + } + } + } + + //Stop the timer + timer.stop(); + + //Return the results + return Answer::new(format!("There are {} Sundays that landed on the first of the months from {} to {}", totalSundays, START_YEAR, END_YEAR), timer.getString()); +} +//Return the day of the week that the date you pass into it is on +fn getDay(orgMonth: i32, orgDay: i32, orgYear: i32) -> DAYS{ + let month = orgMonth; + let mut day = orgDay; + let year = orgYear; + //Make sure the number are within propper bounds + if((month < 1) || (month > 12) || (day < 1) || (day > 31) || (year < 1)){ + return DAYS::ERROR; + } + let mut numDays = 0; + let mut currentYear = 1; + let mut currentMonth = 1; + let mut currentDay = DAYS::SATURDAY as i32; + day -= 1; + + //Add the correct number of days for every year + while(currentYear < year){ + if(isLeapYear(currentYear)){ + numDays += 366; + } + else{ + numDays += 365; + } + currentYear += 1; + } + //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 += 1; + } + //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)){ + 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 as i32; + if(currentDay == DAYS::SUNDAY as i32){ + return DAYS::SUNDAY; + } + else if(currentDay == DAYS::MONDAY as i32){ + return DAYS::MONDAY; + } + else if(currentDay == DAYS::TUESDAY as i32){ + return DAYS::TUESDAY; + } + else if(currentDay == DAYS::WEDNESDAY as i32){ + return DAYS::WEDNESDAY; + } + else if(currentDay == DAYS::THRUSDAY as i32){ + return DAYS::THRUSDAY; + } + else if(currentDay == DAYS::FRIDAY as i32){ + return DAYS::FRIDAY; + } + else if(currentDay == DAYS::SATURDAY as i32){ + return DAYS::SATURDAY; + } + else{ + println!("Hit default error"); + return DAYS::ERROR; + } +} +//Returns true if the year passed to it is a leap year +fn isLeapYear(year: i32) -> bool{ + 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 2.091 milliseconds to solve this problem +*/ diff --git a/src/main.rs b/src/main.rs index b7044a0..cd69649 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,8 +33,8 @@ mod Problems; #[derive(PartialEq)] enum Selections{EMPTY, SOLVE, DESCRIPTION, LIST, EXIT, SIZE} -static problemNumbers: [u32; 19] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18]; +static problemNumbers: [u32; 20] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]; fn main(){ let mut selection = Selections::EMPTY; @@ -203,6 +203,10 @@ fn solveProblem(problemNumber: u32){ println!("{}", Problems::Problem18::getDescription()); println!("{}", Problems::Problem18::solve()); } + else if(problemNumber == 19){ + println!("{}", Problems::Problem19::getDescription()); + println!("{}", Problems::Problem19::solve()); + } } fn descriptionMenu(){ //Give some extra space to print the description @@ -282,6 +286,9 @@ fn printDescription(problemNumber: u32){ else if(problemNumber == 18){ println!("{}", Problems::Problem18::getDescription()); } + else if(problemNumber == 19){ + println!("{}", Problems::Problem19::getDescription()); + } } fn getProblemNumber() -> u32{ println!("Enter a problem number: ");