/* * doomsday.c * A program to test a function dayOfWeek which determines which * day of the week a particular date falls on. * (only for dates after the start of the Gregorian calendar). * * Program stub created by Richard Buckland on 17/03/14 * This program by Sabrina Rispin * Freely licensed under Creative Commons CC-BY-3.0 * * */ //---------------------------72-characters------------------------------ #include <stdio.h> #include <stdlib.h> #include <assert.h> #define THURSDAY 0 #define FRIDAY 1 #define SATURDAY 2 #define SUNDAY 3 #define MONDAY 4 #define TUESDAY 5 #define WEDNESDAY 6 #define TRUE 1 #define FALSE 0 #define DAYS_PER_WEEK 7 int dayOfWeek (int doomsday, int leapYear, int month, int day); void checkValidInput (int doomsday, int leapYear, int month, int day); int findCloseDoomDay (int doomsday, int leapYear, int month, int day); void testPrint (int testGroup); void runUnitTests (void); void testConstants (void); int main (int argc, char * argv[]) { runUnitTests(); testConstants(); printf ("all tests passed - You are awesome!\n"); return EXIT_SUCCESS; } // given the doomsday for a year, and whether or not it is a // leap year, this function return the day of the week for any // given month and day in the year. int dayOfWeek (int doomsday, int leapYear, int month, int day) { int dayOfWeek; int closeDoomDay; checkValidInput (doomsday, leapYear, month, day); closeDoomDay = findCloseDoomDay (doomsday, leapYear, month, day); // Make dayOfWeek a day in the first week of that month // and do the same to the closeDoomDay day = day % DAYS_PER_WEEK; closeDoomDay = closeDoomDay % DAYS_PER_WEEK; // The day - closeDoomDay will show how many days off // the day is from a doomsday day // dayOfWeek = day of the doomsday day - the diff dayOfWeek = doomsday + (day - closeDoomDay); if (dayOfWeek < 0) { // e.g. if the dayOfWeek = -1 (which should be 6) dayOfWeek = dayOfWeek + DAYS_PER_WEEK; } else if (dayOfWeek > (DAYS_PER_WEEK - 1)) { // e.g. if the dayOfWeek = 10 (which should be 3) dayOfWeek = dayOfWeek % DAYS_PER_WEEK; } // Optional print statements: used to manually work out the ans // Useful if assert failure happens /* printf ("doomsday: %d\n", doomsday); printf ("closeDoomDay: %d\n", closeDoomDay); printf ("day: %d\n", day); printf ("difference: %d\n", (day - closeDoomDay)); printf ("dayOfWeek: %d\n\n", dayOfWeek); */ return (dayOfWeek); } void checkValidInput (int doomsday, int leapYear, int month, int day) { // Check for valid inputs assert (doomsday >= THURSDAY && doomsday <= WEDNESDAY); assert (leapYear == TRUE || leapYear == FALSE); assert (month >= 1 && month <= 12); assert (day >= 1 && day <= 31); if (day == 31) { assert (month == 1 || 3 || 5 || 7 || 8 || 10 || 12); } if (month == 2) { if (leapYear) { assert (day >= 1 && day <= 29); } else { assert (day >= 1 && day <= 28); } } } int findCloseDoomDay (int doomsday, int leapYear, int month, int day) { int closeDoomDay; // find a doomsday day in each month if (month >= 1 && month <= 3) { // closest days that falls on the doomsday for Jan, Feb and March if (month == 1) { // Jan closeDoomDay = 3; } else { // Feb and Mar - same day for both closeDoomDay = 0; } // check for leap years (Jan and Feb) if (leapYear && month != 3) { closeDoomDay++; } } else if ((month % 2) == 0) { // The 4/4, 6/6, 8/8, 10/10, 12/12 rule closeDoomDay = month; } else { // The 5/9, 7/11, 9/5, 11/7 rule if (month == 5) { closeDoomDay = 9; } else if (month == 7) { closeDoomDay = 11; } else if (month == 9) { closeDoomDay = 5; } else { closeDoomDay = 7; } } return (closeDoomDay); } void testPrint (int testGroup) { printf("Group %d has passed - You are awesome!\n\n",testGroup); } void testConstants (void) { // Are the days their assumed values assert(THURSDAY == 0); assert(FRIDAY == 1); assert(SATURDAY == 2); assert(SUNDAY == 3); assert(MONDAY == 4); assert(TUESDAY == 5); assert(WEDNESDAY == 6); // DAYS_PER_WEEK is the number of days above assert(DAYS_PER_WEEK == 7); // Basic logic check for TRUE FALSE assert(TRUE != FALSE); printf("\nAll constants are correctly defined.\n"); } void runUnitTests (void) { int testNumber = 0; printf ("Testing group 1: Doomsday's\n"); assert (dayOfWeek (THURSDAY, FALSE, 4, 4) == THURSDAY); assert (dayOfWeek (FRIDAY, FALSE, 6, 6) == FRIDAY); assert (dayOfWeek (MONDAY, FALSE, 8, 8) == MONDAY); assert (dayOfWeek (WEDNESDAY, FALSE, 10, 10) == WEDNESDAY); assert (dayOfWeek (FRIDAY, FALSE, 12, 12) == FRIDAY); assert (dayOfWeek (THURSDAY, FALSE, 9, 5) == THURSDAY); assert (dayOfWeek (FRIDAY, FALSE, 5, 9) == FRIDAY); assert (dayOfWeek (SUNDAY, FALSE, 7, 11) == SUNDAY); assert (dayOfWeek (TUESDAY, FALSE, 11, 7) == TUESDAY); assert (dayOfWeek (WEDNESDAY, FALSE, 3, 7) == WEDNESDAY); testNumber++; testPrint (testNumber); //JANUARY leap year testing printf ("Testing January Leap Year\n"); assert (dayOfWeek (MONDAY, FALSE, 1, 1) == SATURDAY); assert (dayOfWeek (MONDAY, FALSE, 1, 29) == SATURDAY); assert (dayOfWeek (MONDAY, FALSE, 1, 31) == MONDAY); assert (dayOfWeek (WEDNESDAY, TRUE, 1, 1) == SUNDAY); assert (dayOfWeek (WEDNESDAY, TRUE, 1, 29) == SUNDAY); assert (dayOfWeek (WEDNESDAY, TRUE, 1, 31) == TUESDAY); testNumber++; testPrint (testNumber); //FEBRUARY leap year testing printf ("Testing February Leap Year\n"); assert (dayOfWeek (MONDAY, FALSE, 2, 1) == TUESDAY); assert (dayOfWeek (MONDAY, FALSE, 2, 28) == MONDAY); assert (dayOfWeek (TUESDAY, TRUE, 2, 1) == TUESDAY); assert (dayOfWeek (TUESDAY, TRUE, 2, 28) == MONDAY); assert (dayOfWeek (TUESDAY, TRUE, 2, 29) == TUESDAY); testNumber++; testPrint (testNumber); // Test cases further than one week behind doomsday printf ("Testing > 1 week before Doomsday\n"); assert (dayOfWeek (SATURDAY, FALSE, 12, 1) == TUESDAY); assert (dayOfWeek (SATURDAY, FALSE, 10, 1) == THURSDAY); testNumber++; testPrint (testNumber); // Test one week ahead printf ("Testing > 1 week after Doomsday\n"); assert (dayOfWeek (FRIDAY, FALSE, 6, 30) == MONDAY); assert (dayOfWeek (FRIDAY, FALSE, 6, 13) == FRIDAY); testNumber++; testPrint (testNumber); // First day of each month printf ("Testing first day of each month\n"); assert (dayOfWeek (MONDAY, FALSE, 1, 1) == SATURDAY); assert (dayOfWeek (MONDAY, FALSE, 2, 1) == TUESDAY); assert (dayOfWeek (MONDAY, FALSE, 3, 1) == TUESDAY); assert (dayOfWeek (MONDAY, FALSE, 4, 1) == FRIDAY); assert (dayOfWeek (MONDAY, FALSE, 5, 1) == SUNDAY); assert (dayOfWeek (MONDAY, FALSE, 6, 1) == WEDNESDAY); assert (dayOfWeek (MONDAY, FALSE, 7, 1) == FRIDAY); assert (dayOfWeek (MONDAY, FALSE, 8, 1) == MONDAY); assert (dayOfWeek (MONDAY, FALSE, 9, 1) == THURSDAY); assert (dayOfWeek (MONDAY, FALSE, 10, 1) == SATURDAY); assert (dayOfWeek (MONDAY, FALSE, 11, 1) == TUESDAY); assert (dayOfWeek (MONDAY, FALSE, 12, 1) == THURSDAY); assert (dayOfWeek (MONDAY, TRUE, 1, 1) == FRIDAY); assert (dayOfWeek (MONDAY, TRUE, 2, 1) == MONDAY); testNumber++; testPrint (testNumber); // Last day of each month printf ("Testing last day of each month\n"); assert (dayOfWeek (MONDAY, FALSE, 1, 31) == MONDAY); assert (dayOfWeek (MONDAY, FALSE, 2, 28) == MONDAY); assert (dayOfWeek (MONDAY, FALSE, 3, 31) == THURSDAY); assert (dayOfWeek (MONDAY, FALSE, 4, 30) == SATURDAY); assert (dayOfWeek (MONDAY, FALSE, 5, 31) == TUESDAY); assert (dayOfWeek (MONDAY, FALSE, 6, 30) == THURSDAY); assert (dayOfWeek (MONDAY, FALSE, 7, 31) == SUNDAY); assert (dayOfWeek (MONDAY, FALSE, 8, 31) == WEDNESDAY); assert (dayOfWeek (MONDAY, FALSE, 9, 30) == FRIDAY); assert (dayOfWeek (MONDAY, FALSE, 10, 31) == MONDAY); assert (dayOfWeek (MONDAY, FALSE, 11, 30) == WEDNESDAY); assert (dayOfWeek (MONDAY, FALSE, 12, 31) == SATURDAY); assert (dayOfWeek (MONDAY, TRUE, 1, 31) == SUNDAY); assert (dayOfWeek (MONDAY, TRUE, 2, 29) == MONDAY); testNumber++; testPrint (testNumber); //One day before doomsday printf ("Testing one day before doomsday of each relevant month\n"); assert (dayOfWeek (THURSDAY, TRUE, 2, 28) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 2, 27) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 4, 3) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 5, 8) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 6, 5) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 7, 10) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 8, 7) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 9, 4) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 10, 9) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 11, 6) == WEDNESDAY); assert (dayOfWeek (THURSDAY, FALSE, 12, 11) == WEDNESDAY); testNumber++; testPrint (testNumber); //just a test printf ("Just a test.\n"); assert (dayOfWeek (FRIDAY, FALSE, 11, 9) == SUNDAY); testNumber++; testPrint (testNumber); //Test Christmas Day and Boxing Day printf ("Test Christmas Day and Boxing Day\n"); assert (dayOfWeek (SATURDAY, FALSE, 12, 25) == FRIDAY); assert (dayOfWeek (SATURDAY, FALSE, 12, 26) == SATURDAY); testNumber++; testPrint (testNumber); // Test Pi Day printf ("Test Pi Day\n"); assert (dayOfWeek (TUESDAY, FALSE, 3, 14) == TUESDAY); testNumber++; testPrint (testNumber); //Group 11: Test for Unexpected Inputs printf ("Testing group 11: Test for Unexpected Inputs\n"); assert (dayOfWeek (THURSDAY, FALSE, -1, 31) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (THURSDAY, FALSE, 1, 31) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (THURSDAY, FALSE, 2, 29) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (THURSDAY, FALSE, 13, 46) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (7, FALSE, 2, 4) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (8, FALSE, 2, 4) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (9, FALSE, 2, 4) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (-1, FALSE, 2, 4) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (-2, FALSE, 2, 4) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); assert (dayOfWeek (-3, FALSE, 2, 4) != MONDAY || TUESDAY || WEDNESDAY || THURSDAY || FRIDAY || SATURDAY || SUNDAY); testNumber++; testPrint (testNumber); //Test for every 3rd of Ludvig A. Løddesøls birthdays printf ("Test for every 3rd of Ludvig A. Løddesøls birthdays\n"); assert (dayOfWeek (MONDAY, TRUE, 3, 12) == SATURDAY); assert (dayOfWeek (FRIDAY, FALSE, 3, 12) == WEDNESDAY); assert (dayOfWeek (TUESDAY, TRUE, 3, 12) == SUNDAY); assert (dayOfWeek (FRIDAY, FALSE, 3, 12) == WEDNESDAY); assert (dayOfWeek (TUESDAY, FALSE, 3, 12) == SUNDAY); assert (dayOfWeek (SATURDAY, FALSE, 3, 12) == THURSDAY); assert (dayOfWeek (WEDNESDAY, FALSE, 3, 12) == MONDAY); assert (dayOfWeek (SATURDAY, FALSE, 3, 12) == THURSDAY); testNumber++; testPrint (testNumber); // Test for my birthday last 10 year printf ("Test for my birthday last 10 year\n"); assert (dayOfWeek (SATURDAY, FALSE, 11, 18) == WEDNESDAY); assert (dayOfWeek (FRIDAY, FALSE, 11, 18) == TUESDAY); assert (dayOfWeek (THURSDAY, FALSE, 11, 18) == MONDAY); assert (dayOfWeek (WEDNESDAY, TRUE, 11, 18) == SUNDAY ); assert (dayOfWeek (MONDAY, FALSE, 11, 18) == FRIDAY ); assert (dayOfWeek (SUNDAY, FALSE, 11, 18) == THURSDAY); assert (dayOfWeek (SATURDAY, FALSE, 11, 18) == WEDNESDAY ); assert (dayOfWeek (FRIDAY, TRUE, 11, 18) == TUESDAY); assert (dayOfWeek (WEDNESDAY, FALSE, 11, 18) == SUNDAY); assert (dayOfWeek (TUESDAY, FALSE, 11, 18) == SATURDAY); testNumber++; testPrint (testNumber); // Test 1st of Jan on some special year printf ("Test 1st of Jan on some special year\n"); assert (dayOfWeek (TUESDAY, TRUE, 1, 1) == SATURDAY); // year 2000 assert (dayOfWeek (WEDNESDAY, FALSE, 1, 1) == MONDAY); // year 1900 testNumber++; testPrint (testNumber); }
Download file: doomsday.c
(12.6 KB)