Computer Programming Contest Preparation

ToolBox - Source for: 5/518/judged.c



/home/toolbox/public_html/solutions/5/518/judged.c
    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <time.h>
    4 
    5 /*
    6  *  Author: Matthew Eastman <meastman@cct.lsu.edu>
    7  *    Date: 2006-10-03
    8  * Purpose: Contest practice
    9  * Problem: 518 - Time <http://isaac.lsu.edu/udv/v5/518.html>
   10  */
   11 
   12 #define FALSE 0
   13 #define TRUE  1
   14 
   15 /*
   16  * NOTE: struct tm has at least the following members:
   17  * int tm_sec;     // seconds (0 - 60)
   18  * int tm_min;     // minutes (0 - 59)
   19  * int tm_hour;    // hours (0 - 23)
   20  * int tm_mday;    // day of month (1 - 31)
   21  * int tm_mon;     // month of year (0 - 11)
   22  * int tm_year;    // year - 1900
   23  */
   24 struct tm start_time;
   25 struct tm end_time;
   26 int unit_count;
   27 char unit_type; /* y: year, m: month, d: day, h: hour, i: minute, s: second */
   28 
   29 /* debugging function; dumps all of the current data */
   30 void showData()
   31 {
   32     printf("%d %d %d %d %d %d\n", start_time.tm_year, start_time.tm_mon,
   33            start_time.tm_mday, start_time.tm_hour, start_time.tm_min,
   34            start_time.tm_sec);
   35     printf("%d %d %d %d %d %d\n", end_time.tm_year, end_time.tm_mon,
   36            end_time.tm_mday, end_time.tm_hour, end_time.tm_min, end_time.tm_sec);
   37     printf("%d %c\n", unit_count, unit_type);
   38 }
   39 
   40 /* solves the problem when the interval is in months or years */
   41 int solveByMonths()
   42 {
   43     int a, b, c;
   44     int partial = FALSE;
   45 
   46     a = start_time.tm_year * 12 + start_time.tm_mon;
   47     b = end_time.tm_year * 12 + end_time.tm_mon;
   48 
   49     /* see whether or not the first time period starts its first second;
   50      * if it doesn't, we'll have to use the next one */
   51     if ((0 < start_time.tm_sec + start_time.tm_min + start_time.tm_hour) ||
   52             (1 < start_time.tm_mday))
   53         partial = TRUE;
   54     else if (('y' == unit_type) && (0 < start_time.tm_mon))
   55         partial = TRUE;
   56 
   57     if ('y' == unit_type)
   58         {
   59             if (partial)
   60                 a = (start_time.tm_year + 1) * 12;
   61             c = 12;
   62         }
   63     else
   64         {
   65             if (partial)
   66                 a++;
   67             c = 1;
   68         }
   69 
   70     return (b - a) / (c * unit_count);
   71 }
   72 
   73 /* solves the problem when the interval is in days or smaller */
   74 int solveBySeconds()
   75 {
   76     time_t a, b, c;
   77 
   78     /* mktime takes a (struct tm*) and returns seconds since 1970 */
   79     a = mktime(&start_time);
   80     b = mktime(&end_time);
   81 
   82     if ('d' == unit_type)
   83         c = 86400;
   84     else if ('h' == unit_type)
   85         c = 3600;
   86     else if ('i' == unit_type)
   87         c = 60;
   88     else
   89         c = 1;
   90 
   91     /* lower the end time to a unit_type (hour, minute, ...) boundary;
   92      * we accomplished the same thing in solveByMonths() by raising the start
   93      * time to the next boundary */
   94     b = (b / c) * c;
   95 
   96     return (int)((b - a) / (c * unit_count));
   97 }
   98 
   99 void solve()
  100 {
  101     int answer;
  102 
  103     if (('y' == unit_type) || ('m' == unit_type))
  104         answer = solveByMonths();
  105     else
  106         answer = solveBySeconds();
  107 
  108     printf("%d\n", answer);
  109 }
  110 
  111 int getInput()
  112 {
  113     char a, b;
  114 
  115     /* NOTE: libc's time functions treat tm_year as years since 1900 and
  116      * tm_mon as 0-indexed */
  117 
  118     /* read in the start time */
  119     if (6 != scanf("%d %d %d %d %d %d", &(start_time.tm_year),
  120                    &(start_time.tm_mon), &(start_time.tm_mday), &(start_time.tm_hour),
  121                    &(start_time.tm_min), &(start_time.tm_sec)))
  122         return FALSE;
  123     start_time.tm_year -= 1900;
  124     start_time.tm_mon--;
  125 
  126     /* read in the end time */
  127     scanf("%d %d %d %d %d %d", &(end_time.tm_year), &(end_time.tm_mon),
  128           &(end_time.tm_mday), &(end_time.tm_hour), &(end_time.tm_min),
  129           &(end_time.tm_sec));
  130     end_time.tm_year -= 1900;
  131     end_time.tm_mon--;
  132 
  133     /* read in the time period
  134      * NOTE: unit_type is one of (y: year, m: month, d: day, h: hour,
  135      * i: minute, s: second) */
  136     scanf("%d %c%c%*s", &unit_count, &a, &b);
  137     if ((a == 'm') && (b == 'i'))
  138         unit_type = 'i';
  139     else
  140         unit_type = a;
  141 
  142     return TRUE;
  143 }
  144 
  145 int main()
  146 {
  147     /* perform all of the operations in the UTC time zone so that we don't
  148      * have to deal with daylight savings or negative unix timestamps */
  149     setenv("TZ", "", 1);
  150     tzset();
  151 
  152     while (getInput())
  153         {
  154             /* showData(); */
  155             solve();
  156         }
  157 
  158     return EXIT_SUCCESS;
  159 }
  160 
  161