Project Euler problem 19 - How many Sundays fell on the first Here's the problem:


  How many Sundays fell on the first of the month during the twentieth
  century (1 Jan 1901 to 31 Dec 2000)?


And here's my code:

#include &lt;stdio.h&gt;

int main(void){
    int months[12] = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 };
    int year=1901;
    int dayoftheweek=2;  //put a 2 because the 1 jan 1901 is tuesday. 0-sunday 6-Saturday
    int sunday=0;
    int firstsundays=0;

    while(year&lt;=2000){
        if(year%4==0)    //checking if it's a leap year
            months[1]=29;

        for (int i = 0; i &lt; 12; ++i) {
            for (int d = 1; d &lt;= months[i]; d++){
                if(dayoftheweek==7)  //reset the week
                    dayoftheweek=0;

                if(dayoftheweek==sunday &amp;&amp; d==1)
                    firstsundays++;

                dayoftheweek++;
            }
        }

        months[1]=28;
        year++;
    }

    printf("There are %d Sundays that fell on the first of the month\n", firstsundays);

    return 0;
}


What could I improve?
The loops could be clearer:


The outermost loop is actually spread across three lines: int year=1901, while(year&lt;=2000), and year++.  It should be written as a for loop.
i should be renamed to month or m.
The exceptional case for leap years is awkward: you sometimes clobber the February entry at the top of the loop, then reset it at the end.  I'd consider such mutations to be a hack that makes the code harder to understand.  It also makes the code harder to maintain, since you have hard-coded 29 and 28 in scattered places.


As for the algorithm itself… you should be able to do better than advancing a day at a time through an entire century.  Why not advance a month at a time?

#include &lt;stdio.h&gt;

static const int *month_lengths(int year) {
    static const int NON_LEAP_YEAR[] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    static const int LEAP_YEAR[] = {
        31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    return (year % 4 == 0 &amp;&amp; (year % 100 != 0 || year % 400 == 0)) ?
        LEAP_YEAR : NON_LEAP_YEAR;
}

int main(void) {
    int first_sundays = 0;
    int day_of_the_week = 2;    // 0 = Sun, 6 = Sat.  1 Jan 1901 was a Tuesday.
    for (int year = 1901; year &lt;= 2000; ++year) {
        const int *lengths = month_lengths(year);
        for (int month = 0; month &lt; 12; month++) {
            if (day_of_the_week == 0) {
                first_sundays++;
            }
            day_of_the_week = (day_of_the_week + lengths[month]) % 7;
        }
    }
    printf("There are %d Sundays that fell on the first of the month\n",
           first_sundays);
}