Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Find the 256th day of a given year and print it as dd.mm.yyyy. The 256th day is always in September; the only thing that moves it is February's length. Use the Julian leap rule (year % 4 == 0) for years up to 1917, the Gregorian rule (divisible by 400, or by 4 but not 100) from 1919 on, and treat 1918 specially because that February lost 13 days. The answer is 12.09 in a leap year, 13.09 in a common year, and 26.09 in 1918.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you can encode era-dependent leap-year rules correctly, remember the 1918 Julian-to-Gregorian transition that deleted 13 days, and format the result as a fixed-width date — careful branching, not algorithmic depth.
Where candidates slip
Applying the Gregorian % 100 / % 400 exceptions to pre-1918 (Julian) years, or forgetting 1918 entirely and printing 13.09.1918 instead of 26.09.1918.
How to stand out
Separate the three regimes out loud — Julian (≤1917), the 1918 transition, Gregorian (≥1919) — and explain why only February's length can shift the 256th day.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewFind the 256th dayyear == 1918?YesNoExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Month Accumulation — Count Days Across Months
1Hint 1Explore hintHide hint
Build the 12 month lengths for this specific year, getting February right via the era's leap rule (and the 1918 special case).
2Hint 2Explore hintHide hint
Walk month by month, subtracting each month's length from a running 'remaining = 256' until remaining no longer exceeds the current month.
3Hint 3Explore hintHide hint
When the loop stops, `remaining` is the day-of-month and the current month index gives the month. Format as dd.mm.yyyy.
A · Core idea
This version generalises to any day-of-year, not just 256, by walking the calendar.
Building the month table. The only month whose length varies is February. Decide it first: 15 days if year == 1918, otherwise 29 if the era's leap rule fires (Julian % 4 for ≤ 1917, Gregorian % 400 / % 4 / % 100 for ≥ 1919), otherwise 28. Plug that into the standard [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31].
Walking to the target day. Start remaining = 256. For each month, if remaining is larger than that month's length, the target lies further on — subtract the month and move to the next. Stop the moment remaining <= days[month]: the target falls inside this month, and remaining is now the day number. This is the same logic a calendar library uses to convert a day-of-year into a date.
Why it lands in September. January through August sum to 243 (common), 244 (leap), or 230 (1918). In every case remaining after August is between 1 and 30, so the loop halts on the September entry — confirming the closed-form shortcut the optimal approach uses.
Why mention it. It is dependable and obviously correct, and it makes the September observation concrete rather than asserted. The optimal version simply skips the walk because we know the answer is always September.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
year = 1918How to read it:Each month peels off until the remaining count fits — it always stops in September.
26.09.1918C · Code with teaching comments
Reference implementation previewpublic String dayOfProgrammer(int year) { int feb; if (year == 1918) { feb = 15; // transition year } else if (year < 1918) {Explore the full codeHide the full code
D · Why it works and complexityO(1) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
Converting a day-of-year to a date is 'subtract month lengths until the day fits'. Getting February right per era is the only hard part; the walk itself is mechanical.
ComplexityO(1) time, O(1) space — At most 12 months are scanned regardless of input, and a fixed-size array of month lengths is used — constant time and space.
E · Edge cases and pitfalls3Using the Gregorian leap rule for pre-1918 years — Julian has no % 100 / % 400 exceptions.Explore edge casesHide edge cases
Pitfalls
- Using the Gregorian leap rule for pre-1918 years — Julian has no % 100 / % 400 exceptions.
- Setting February to 28 or 29 in 1918 instead of 15.
- Comparing with `>=` instead of `>` in the loop, landing on the wrong month boundary.
Approach 2 of 2 · Optimal
Direct Branch — September Closed Form (Optimal)
1Hint 1Explore hintHide hint
You already know Jan–Aug = 243 (common) / 244 (leap), so day 256 is September 13 or 12 — no month walk needed.
2Hint 2Explore hintHide hint
Branch the leap decision by era: Julian (% 4) for ≤ 1917, Gregorian (% 400, % 4, % 100) for ≥ 1919.
3Hint 3Explore hintHide hint
Handle 1918 as a hardcoded 26.09.1918. Everything else is '12 or 13, dot 09, dot year'.
A · Core idea
Since the target never leaves September, collapse the whole calendar into three printed strings.
Why September is guaranteed. January through August is 31+28+31+30+31+30+31+31 = 243 days in a common year and 244 in a leap year. Day 256 is therefore 256 − 243 = 13 (common) or 256 − 244 = 12 (leap) of September. In 1918, those eight months total 230 because February held only 15 days, so day 256 is 256 − 230 = 26 of September.
The leap branch by era. For years up to 1917 the calendar is Julian: a year is a leap year exactly when year % 4 == 0, with no century exceptions. For 1919 onward it is Gregorian: a leap year is divisible by 400, or divisible by 4 but not by 100. Applying the wrong rule near century boundaries (1800, 1900) is the most common silent error — under Julian, 1800 is a leap year; under Gregorian it would not be.
The 1918 special case. This single year is neither cleanly Julian nor Gregorian for our purposes — its February was truncated to 15 days. Hardcoding 26.09.1918 is clearer and safer than trying to fold it into the leap logic.
Assembling the output. Everything reduces to choosing 12 or 13 for the day, then appending .09. and the year. Zero-padding matters: the format is dd.mm.yyyy, so the month is always 09, never 9.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
year = 1800Interactive diagram
Three regimes, three day numbers
transition?The era picks the leap rule; the leap rule picks 12 vs 13; 1918 is its own answer.
12.09.1800C · Code with teaching comments
D · Why it works and complexityO(1) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The 256th day can only move when February's length moves, and February only touches the Jan–Aug prefix. That is why three printed strings cover every year in range — the rest is choosing the correct leap rule for the era.
ComplexityO(1) time, O(1) space — A couple of comparisons and a string build — constant work, constant space, independent of the year.
E · Edge cases and pitfalls6year = 1900 — Julian (≤ 1917): 1900 % 4 == 0 → leap → 12.09.1900. Under Gregorian it would be common — the era matters.Explore edge casesHide edge cases
Edge cases handled
year = 1900Julian (≤ 1917): 1900 % 4 == 0 → leap → 12.09.1900. Under Gregorian it would be common — the era matters.year = 2000Gregorian: 2000 % 400 == 0 → leap → 12.09.2000. The 400-exception keeps it a leap year.year = 1917Last Julian year: 1917 % 4 != 0 → common → 13.09.1917.
Pitfalls
- Forgetting 1918 entirely and printing 13.09.1918 instead of 26.09.1918.
- Applying Gregorian century rules to years ≤ 1917 (e.g. wrongly calling 1900 common).
- Dropping the zero-pad and printing 13.9.2017 instead of 13.09.2017.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic String dayOfProgrammer(int year) { if (year == 1918) { return "26.09.1918"; // transition year } boolean leap;Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Wrong leap rule for the era
Before 1918 the calendar is Julian: every multiple of 4 is a leap year. Applying Gregorian century exceptions wrongly marks 1700, 1800, 1900 as common.
Explore the code comparisonHide the code comparison
Wrong leap rule for the era
Before 1918 the calendar is Julian: every multiple of 4 is a leap year. Applying Gregorian century exceptions wrongly marks 1700, 1800, 1900 as common.
Don't write this
boolean leap = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); // wrong for year <= 1917Write this instead
boolean leap = (year < 1918)
? year % 4 == 0
: year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);2Missing the 1918 transition
1918 deleted 13 days from February, so the 256th day is 26.09, not the usual 13.09. Folding it into leap logic silently gets it wrong.
Explore the code comparisonHide the code comparison
Missing the 1918 transition
1918 deleted 13 days from February, so the 256th day is 26.09, not the usual 13.09. Folding it into leap logic silently gets it wrong.
Don't write this
leap = year % 400 == 0 or (year % 4 == 0 and year % 100 != 0)
return f"{'12' if leap else '13'}.09.{year}" # gives 13.09.1918Write this instead
if year == 1918:
return "26.09.1918"
# ... normal leap logic for every other year3Unpadded date format
The required format is dd.mm.yyyy. September must print as 09 and the day as two digits; 13.9.2017 fails the checker.
Explore the code comparisonHide the code comparison
Unpadded date format
The required format is dd.mm.yyyy. September must print as 09 and the day as two digits; 13.9.2017 fails the checker.
Don't write this
return f"{day}.{9}.{year}" # 13.9.2017Write this instead
return f"{day:02d}.09.{year}" # 13.09.2017Revise
Carry the pattern into the interview
Pattern to remember
Branch on the calendar, then closed-form the date
Code pattern to memorize
if year == 1918: return "26.09.1918"
if year < 1918: leap = (year % 4 == 0) # Julian
else: leap = (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0) # Gregorian
return ("12" if leap else "13") + ".09." + str(year)Rules to remember
- 11918 is the transition year and the trap: switching from Julian to Gregorian deleted 13 days that February, so the 256th day is 26.09.1918. Hardcode it.
- 2Years ≤ 1917 use the Julian rule — leap iff
year % 4 == 0. The% 100and% 400exceptions do not exist yet. - 3Years ≥ 1919 use the Gregorian rule — leap iff divisible by 400, or divisible by 4 but not by 100.
- 4The 256th day is always in September for normal years: Jan–Aug is 243 days common / 244 leap, so day 256 is the 13th or 12th of September.
- 5Output is fixed-width
dd.mm.yyyy— zero-pad day and month (26.09.1918), never26.9.1918.
Use this pattern when
- Date / calendar arithmetic with calendar-system changes
- A fixed day-of-year mapped to a concrete date
- Leap-year reasoning where the rule depends on the era
- A small set of regimes you can branch over in O(1)
Choose another pattern when
- Arbitrary date differences across many years → use a date library or epoch days
- Time zones / hours / minutes involved → far beyond integer day counting
- You must handle every historical calendar quirk → this problem only spans one transition
- The day-of-year is an input that varies → loop over months instead of hardcoding September
Interview takeaway
Calendar problems are branch-then-count: pick the right leap rule for the era, remember the one-off transition year, then map the day-of-year to a date. Day of the Programmer collapses to three cases because the 256th day never leaves September.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternBranch-then-count calendar arithmetic. Identify which regime (era, special year) applies, apply that regime's rule, then map the day-of-year to a concrete date. Day of the Programmer needs only three cases because the answer never leaves September.
Practice queueDirect variations and pattern siblings
Direct follow-ups