fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. // ASSUMPTIONS
  5. //
  6. // - I use the definition of perfect month that's on its wikipedia which states that
  7. // it's gotta be in Feb, in non leap year, and the 1st feb starts on either sunday or monday
  8. // depends on each person's first day on their own calendar
  9. //
  10. // - I made an assumption that the date input from user will always be the first of january of that year
  11. // which means, if a user put 2026 as the input, I'll assume it's the 1st January of 2026
  12. // making the next perfect month will be 02-2026 and the prev one will be 2015-02 (if we use sunday)
  13.  
  14. int firstDayOfCalendar = 0; // default = sunday
  15.  
  16. // sakamoto algo's to find the day of the week of a certain date
  17. int getDayOfTheWeek(int y, int m, int d){
  18.  
  19. int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
  20.  
  21. if(m < 3){
  22. y -= 1;
  23. }
  24.  
  25. // sunday: 0 ; monday: 1 ; and so on ...
  26. return ((y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7);
  27.  
  28. }
  29.  
  30. bool isLeapYear(int year){
  31. return(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
  32. }
  33.  
  34. void nearestPerfectMonth(int year){
  35. int prev = -1;
  36. int next = -1;
  37. bool foundPrev = false;
  38. bool foundNext = false;
  39. int i = 0;
  40.  
  41. while(!(foundPrev && foundNext)){
  42.  
  43. if(!foundPrev && !isLeapYear(year - i -1) && getDayOfTheWeek((year - i -1), 2, 1) == firstDayOfCalendar){
  44. prev = year - i -1;
  45. foundPrev =true;
  46. }
  47.  
  48. if(!foundNext && !isLeapYear(year + i) && getDayOfTheWeek((year + i), 2, 1) == firstDayOfCalendar){
  49. next = year + i;
  50. foundNext = true;
  51. }
  52.  
  53. i++;
  54. }
  55.  
  56. cout << "> { prev: \"" << prev << "-02\", next: \"" << next << "-02\" }";
  57.  
  58. }
  59.  
  60. int main(){
  61. int year;
  62. string firstDay;
  63. cout << "Enter the first day on your calendar (monday/sunday): ";
  64. cin >> firstDay;
  65. transform(firstDay.begin(), firstDay.end(), firstDay.begin(), ::tolower);
  66. if(firstDay == "monday"){
  67. firstDayOfCalendar = 1;
  68. }
  69. else if(firstDay == "sunday"){
  70. firstDayOfCalendar = 0;
  71. }
  72. else{
  73. cerr << "invalid first day of calendar, defaulted into sunday\n";
  74. }
  75.  
  76. cout << "Enter the year: ";
  77. cin >> year;
  78. nearestPerfectMonth(year);
  79.  
  80. return 0;
  81. }
Success #stdin #stdout 0.01s 5292KB
stdin
sunday
2026
stdout
Enter the first day on your calendar (monday/sunday): Enter the year: > { prev: "2015-02", next: "2026-02" }