Computer Programming Contest Preparation

ToolBox - Source for: 6/602/judged.c



/home/toolbox/public_html/solutions/6/602/judged.c
    1 #include <stdio.h>
    2 #include <string.h>
    3 #include <sys/types.h>
    4 #include <sys/stat.h>
    5 #include <fcntl.h>
    6 #include <stdint.h>
    7 #include <math.h>
    8 #include <stdlib.h>
    9 
   10 /*
   11  *  Author: Matthew Eastman
   12  *    Date: 2006-06-15
   13  * Purpose: Practice
   14  * Problem: 602 - What Day Is It? <http://isaac.lsu.edu/udv/v6/602.html>
   15  */
   16 
   17 #define TRUE  (1 == 1)
   18 #define FALSE (1 != 1)
   19 
   20 #define DEBUG if (FALSE)
   21 
   22 #define CALENDAR_INVALID   0
   23 #define CALENDAR_JULIAN    1
   24 #define CALENDAR_GREGORIAN 2
   25 
   26 int date_year, date_month, date_day;
   27 
   28 int known_julian[] = {1650, 1, 1, 2};    /* 1650/01/01 was a Tuesday */
   29 int known_gregorian[] = {1950, 1, 1, 0}; /* 1950/01/01 was a Sunday  */
   30 
   31 int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
   32 char months[][15] = {"", "January", "February", "March", "April", "May",
   33                      "June", "July", "August", "September", "October", "November", "December"
   34                     };
   35 char weekdays[][15] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
   36                        "Friday", "Saturday"
   37                       };
   38 
   39 int days_in_month(int, int);
   40 int date_compare(int, int, int, int, int, int);
   41 int check_date();
   42 int is_leap_year(int);
   43 int date_distance(int, int, int, int, int, int);
   44 
   45 void init()
   46 {
   47     /* FUNCTION init */
   48 } /* FUNCTION init */
   49 
   50 void dump()
   51 {
   52     /* FUNCTION dump */
   53 } /* FUNCTION dump */
   54 
   55 int getInput()
   56 {
   57     /* FUNCTION getInput */
   58     int dataReadFlag;
   59 
   60     scanf("%d %d %d", &date_month, &date_day, &date_year);
   61     if (0 == date_year)
   62         dataReadFlag = FALSE;
   63     else
   64         dataReadFlag = TRUE;
   65 
   66     return (dataReadFlag);
   67 } /* FUNCTION getInput */
   68 
   69 int days_in_month(int year, int month)
   70 {
   71     int days;
   72 
   73     if ((2 == month) && is_leap_year(year))
   74         days = 29;
   75     else
   76         days = month_days[month];
   77 
   78     return days;
   79 }
   80 
   81 /* compares 2 dates; return values are similar to strcmp
   82  * ymd1 < ymd2 -> negative
   83  * ymd1 > ymd2 -> positive
   84  * ymd1 = ymd2 -> 0
   85  */
   86 int date_compare(int y1, int m1, int d1, int y2, int m2, int d2)
   87 {
   88     int status;
   89 
   90     if (y1 != y2)
   91         status = y1 - y2;
   92     else if (m1 != m2)
   93         status = m1 - m2;
   94     else
   95         status = d1 - d2;
   96 
   97     return status;
   98 }
   99 
  100 /* checks a given date for validity and calendar type */
  101 int check_date()
  102 {
  103     int calendar_type;
  104 
  105     if (12 < date_month)
  106         calendar_type = CALENDAR_INVALID;
  107     else if (days_in_month(date_year, date_month) < date_day)
  108         calendar_type = CALENDAR_INVALID;
  109     else if (date_compare(date_year, date_month, date_day, 1752, 9, 2) <= 0)
  110         calendar_type = CALENDAR_JULIAN;
  111     else if (date_compare(date_year, date_month, date_day, 1752, 9, 14) >= 0)
  112         calendar_type = CALENDAR_GREGORIAN;
  113     else
  114         calendar_type = CALENDAR_INVALID;
  115 
  116     return calendar_type;
  117 }
  118 
  119 int is_leap_year(int year)
  120 {
  121     int status;
  122 
  123     if (1752 >= year) /* julian */
  124         {
  125             if (0 == year % 4)
  126                 status = TRUE;
  127             else
  128                 status = FALSE;
  129         }
  130     else /* gregorian */
  131         {
  132             if (0 != year % 4)
  133                 status = FALSE;
  134             else if ((0 == year % 100) && (0 != year % 400))
  135                 status = FALSE;
  136             else
  137                 status = TRUE;
  138         }
  139 
  140     return status;
  141 }
  142 
  143 /* calculate the distance (in days, possibly mod 7) from ymd1 to ymd2 */
  144 int date_distance(int year1, int month1, int day1, int year2, int month2,
  145                   int day2)
  146 {
  147     int distance;
  148     int i;
  149 
  150     if (date_compare(year1, month1, day1, year2, month2, day2) > 0)
  151         {
  152             distance = -1 * date_distance(year2, month2, day2, year1, month1,
  153                                           day1);
  154         }
  155 
  156     else if ((year1 == year2) && (month1 == month2))
  157         {
  158             distance = day2 - day1;
  159         }
  160 
  161     else if (year1 == year2)
  162         {
  163             distance = days_in_month(year1, month1) - day1;
  164 
  165             for (i = month1 + 1; i < month2; i++)
  166                 {
  167                     distance += days_in_month(year1, i);
  168                 }
  169 
  170             distance += day2;
  171         }
  172 
  173     else
  174         {
  175             distance = days_in_month(year1, month1) - day1;
  176 
  177             for (i = month1 + 1; i < 13; i++)
  178                 {
  179                     distance += days_in_month(year1, i);
  180                 }
  181 
  182             for (i = year1 + 1; i < year2; i++)
  183                 {
  184                     if (is_leap_year(i))
  185                         distance += 366;
  186                     else
  187                         distance += 365;
  188                     distance %= 7;
  189                 }
  190 
  191             for (i = 1; i < month2; i++)
  192                 {
  193                     distance += days_in_month(year2, i);
  194                 }
  195 
  196             distance += day2;
  197         }
  198 
  199     return distance;
  200 }
  201 
  202 void process()
  203 {
  204     /* FUNCTION process */
  205     int calendar_type;
  206     int distance;
  207     int weekday;
  208     int *base_date;
  209 
  210     calendar_type = check_date();
  211     if (CALENDAR_JULIAN == calendar_type)
  212         base_date = known_julian;
  213     else if (CALENDAR_GREGORIAN == calendar_type)
  214         base_date = known_gregorian;
  215 
  216     if (CALENDAR_INVALID == calendar_type)
  217         {
  218             printf("%d/%d/%d is an invalid date.\n", date_month, date_day,
  219                    date_year);
  220         }
  221     else
  222         {
  223             distance = date_distance(base_date[0], base_date[1], base_date[2],
  224                                      date_year, date_month, date_day);
  225             weekday = (base_date[3] + distance) % 7;
  226             if (0 > weekday)
  227                 weekday += 7;
  228             printf("%s %d, %d is a %s\n", months[date_month], date_day, date_year,
  229                    weekdays[weekday]);
  230         }
  231 } /* FUNCTION process */
  232 
  233 int main ()
  234 {
  235     /* main */
  236     int moreToDo;
  237 
  238     init();
  239     moreToDo = getInput();
  240     while (moreToDo)
  241         {
  242             /* while */
  243             process();
  244             moreToDo = getInput();
  245         } /* while */
  246 
  247     return EXIT_SUCCESS;
  248 } /* main */
  249 
  250