/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