basics · intermediate · ~20 min
Apply a closed-form formula with several branching cases.
Compute the day of the week for any Gregorian date using Zeller's congruence — a closed-form formula.
Implement int day_of_week(int y, int m, int d) that returns the weekday of the date (y, m, d), encoded as 0=Saturday, 1=Sunday, 2=Monday, ..., 6=Friday.
Apply Zeller's congruence (Gregorian form):
m < 3, treat the month as 13 or 14 of the previous year: set m += 12 and y -= 1.K = y % 100 and J = y / 100.h = (d + 13*(m+1)/5 + K + K/4 + J/4 - 2*J) mod 7, normalised to 0..6.A Gregorian year y, month m (1..12), and day d (1..31).
Returns the weekday index 0..6 (0=Saturday).
day_of_week(2024, 1, 1) -> 2 (Monday)
day_of_week(2000, 1, 1) -> 0 (Saturday)
day_of_week(2024, 12, 25) -> 4 (Wednesday)
% can yield a negative result, so normalise with ((h % 7) + 7) % 7.Calendar arithmetic shows up in log timestamps, scheduling, and security policies. Zeller's congruence is a clean way to teach modular branching.
A Gregorian date as ints y, m (1..12), d (1..31).
The weekday index 0..6, where 0=Saturday.
Pure arithmetic, no system calls. Apply the Jan/Feb shift and normalise negative modulo.
int day_of_week(int y, int m, int d) { /* TODO */ return 0; }
Forgetting the Jan/Feb shift. Mishandling negative modulo (C99: (-1) % 7 == -1).
Jan/Feb (shift), year 2000 (boundary), pre-Gregorian years (formula doesn't apply).
O(1).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.