diff --git a/solutions/c/meetup/1/meetup.c b/solutions/c/meetup/1/meetup.c new file mode 100644 index 0000000..c4e0e2f --- /dev/null +++ b/solutions/c/meetup/1/meetup.c @@ -0,0 +1,73 @@ +#include "meetup.h" +#include + +static inline int day_of_week(int y, int m, int d); +static inline int get_day_index(const char *day); +static inline int get_days_in_month(int year, int month); + +// There are six week values to consider: first, second, third, fourth, last, teenth. +int meetup_day_of_month(unsigned int year, unsigned int month, const char *week, const char *day){ + int days_in_month = get_days_in_month(year, month); + int target_day = get_day_index(day); + int first_day_of_month = day_of_week(year, month, 1); + + int first_occurrence = (target_day - first_day_of_month + 7) % 7 + 1; + + if (strcmp(week, "first") == 0) return first_occurrence; + if (strcmp(week, "second") == 0) return first_occurrence + 7; + if (strcmp(week, "third") == 0) return first_occurrence + 14; + if (strcmp(week, "fourth") == 0) return first_occurrence + 21; + + if (strcmp(week, "teenth") == 0) { + if (first_occurrence + 7 >= 13) return first_occurrence + 7; + return first_occurrence + 14; + } + + if (strcmp(week, "last") == 0) { + int res = first_occurrence + 21; + if (res + 7 <= days_in_month) res += 7; + return res; + } + + return -1; +} + +static inline int is_leap(int year) { + if (year % 400 == 0) + return 1; + if (year % 100 == 0) + return 0; + if (year % 4 == 0) + return 1; + return 0; +} + +static inline int get_days_in_month(int year, int month) { + if (month == 2) { + return is_leap(year) ? 29 : 28; + } + + if (month == 1 || month == 3 || month == 5 || month == 7 || + month == 8 || month == 10 || month == 12) { + return 31; + } + + return 30; +} + +static inline int get_day_index(const char *day){ + const char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + + for (int i = 0; i < 7; i++){ + if (strcmp(day, days[i]) == 0) return i; + } + + return -1; +} + +// Sakamoto's algorithm +static inline int day_of_week(int y, int m, int d) { + static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; + y -= m < 3; + return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; +} diff --git a/solutions/c/meetup/1/meetup.h b/solutions/c/meetup/1/meetup.h new file mode 100644 index 0000000..1a78268 --- /dev/null +++ b/solutions/c/meetup/1/meetup.h @@ -0,0 +1,7 @@ +#ifndef MEETUP_H +#define MEETUP_H + +int meetup_day_of_month(unsigned int year, unsigned int month, const char *week, + const char *day_of_week); + +#endif