From c751359c3fd4c743d2e99ef22e0fff7bb586e26a Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 1 Apr 2020 12:10:59 -0400 Subject: [PATCH] Project Euler / Problem 19 --- project_euler/Problem 19/sol1.c | 120 ++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 project_euler/Problem 19/sol1.c diff --git a/project_euler/Problem 19/sol1.c b/project_euler/Problem 19/sol1.c new file mode 100644 index 00000000..70fb7f16 --- /dev/null +++ b/project_euler/Problem 19/sol1.c @@ -0,0 +1,120 @@ +#include + +/** + * returns number of days in a month. + * Month is identified by an integer - + * 0 = Jan and 11 = December + * For February, adjust for leap year outside the function. + **/ +char get_month_days(short month) +{ + if (month == 1) /* February has 28 days. Adjust leap year in the loop */ + return 28; + else if (month <= 6) /* odd months till July have 30 days - Jan = 0 (even)*/ + { + if (month & 0x01) + return 30; + else + return 31; + } else if (month >= 7) /* odd months after July have 31 days*/ + { + if (month & 0x01) + return 31; + else + return 30; + } + /* should never reach here! */ + perror("Should never have reached this point!\n"); + return -1; +} + +/** + * return 1 if input year is a leap year + * otherwise, return 0 + **/ +char is_leap_year(short year) +{ + if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) + return 1; + + return 0; +} + +#ifdef DEBUG +const char* day_string(int day) +{ + switch(day) + { + case 0: + return "Sunday"; + case 1: + return "Monday"; + case 2: + return "Tuesday"; + case 3: + return "Wednesday"; + case 4: + return "Thursday"; + case 5: + return "Friday"; + case 6: + return "Saturday"; + default: + return "Shouldnt see this!"; + } +} +#endif + + +int main(int argc, char **argv) +{ + int count_sundays = 0; + const short start_year = 1901; + const short end_year = 2000; + + /** + * Let us identify days i.e., Sunday thru Saturday with integers - 0 thru 6 respectively + * Jan 1 1901 was a Tuesday + **/ + char start_day = 2; + + for (int year = start_year; year <= end_year; year++) + { + char is_leap = is_leap_year(year); + for (char month = 0; month < 12; month ++) + { + /** + * These two for-loops count the start of day for the next month. Hence, + * we have to skip the last December count */ + if (year == end_year && month == 11) + continue; + + int days = get_month_days(month); + + if (is_leap && month == 1) /* for a leap year february, add a day */ + days ++; + + #ifdef DEBUG + if (year == end_year) + { + printf("Year: %d\t Month: %d\t Days: %d\t First of day: %s\n", year, month, days, day_string(start_day)); + } + #endif + + /** Main Algorithm: + * every week has 7 days hence, the start of next day would be modulo 7 + * add to this, the current start date and ensure the result is still + * modulo 7! + **/ + start_day = ((days % 7) + start_day) % 7; + + /* If start-day is a Sunday, increment counter */ + if (start_day == 0) + count_sundays ++; + } + } + + printf("Total number of Sundays that happened on the 1st of a month in the last century: %d\n", count_sundays); + + return 0; +} \ No newline at end of file