C++ :
string dayOfProgrammer(int year) {
//Julian calendar is 13 days behind the Gregorian calendar
vector<int> noOfDaysInMonths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int month = 0, day = 0, dayOfTheProgrammer = 256;
string date = "", monthStr = "", dayStr = "";
if(year <= 1917 || year > 1918){
//using Julian calendar or Gregorian calendar fully
if((year <= 1917 && year % 4 == 0) ||
(year > 1918 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))){
//leap years in either calendar
noOfDaysInMonths[1] = 29;
}
}else{
//year 1918: the messy switch year and it's not a leap year
noOfDaysInMonths[1] = 15;
}
for(int i = 0; i < noOfDaysInMonths.size(); i++){
dayOfTheProgrammer = dayOfTheProgrammer - noOfDaysInMonths[i];
if(dayOfTheProgrammer < noOfDaysInMonths[i+1]){
month = i + 2;
day = dayOfTheProgrammer;
break;
}
}
//formatting date
if(day < 10){
dayStr = "0";
}
if(month < 10){
monthStr = "0";
}
dayStr += to_string(day);
monthStr += to_string(month);
date = dayStr + "." + monthStr + "." + to_string(year);
return date;
}
Explanation:
Happy Russian birthday programmers! This is a fun one. First, check for leap years in both the Julian and Gregorian calendars in the during or before 1917, and the years after 1918 . If it’s a leap year, set the month of Feb to 29 days instead of the usual 28.
Next, for the messy year 1918, change the number of days in Feb to 15, since the day starts from Feb 14. This is counting the day Feb 14 itself, to the day Feb 28 (1918 is NOT a leap year in either calendar).
In the for loop, deduct date from the dayOfTheProgrammer until it is lesser than the next month. The number remaining in the dayOfTheProgrammer variable becomes the day, and the month is the index i + 2 (+1 due to for loop counting from 0, another +1 due to assigning it to next month).
The final part is just string formatting, if day or month is < 10, add a 0 to the dayStr/monthStr string before putting in the actual number day/month respectively.