Euler Problem 19

Euler Problem 19 asks:

'You are given the following information, but you may prefer to do some
'research for yourself.
'
'    * 1 Jan 1900 was a Monday.
'    * Thirty days has September,
'      April, June and November.
'      All the rest have thirty-one,
'      Saving February alone,
'      Which has twenty-eight, rain or shine.
'      And on leap years, twenty-nine.
'    * A leap year occurs on any year evenly divisible by 4, but not on a
'century unless it is divisible by 400.
'
'How many Sundays fell on the first of the month during the twentieth
'century (1 Jan 1901 to 31 Dec 2000)?

Wow. First thought: Euler actually got the century right. Math-minded indeed. Second thought: I need a day counter, a week counter, a month counter, a leap year checker. That’s a lot of conditionals. No wonder this is here. Third thought: I’m doing this in Excel. Piece of cake. This may be the only one aimed right at us, if not intentionally. Here’s my code. Ran in under a second.

Sub Problem_019()  
   Dim Start   As Date
   Dim Answer  As Long
   Dim T       As Single
 
   T = Timer
   Start = DateSerial(1901, 1, 1)
 
   Do While Start <  DateSerial(2001, 1, 1)
      If Weekday(Start) = vbSunday And Day(Start) = vbSunday Then
         Answer = Answer + 1
      End If
      Start = Start + 1
   Loop
 
   Debug.Print Answer; "  Time:", Timer - T
 
End Sub

Coded it up. It ran the first time, and I checked in with the right answer. I was feeling so good until I saw the pencil and paper approach of those who’d solved it …100 years with 12 months per year over 7 days

…mrt

5 Comments

  1. Tushar Mehta says:

    Or, use the Excel formula =SUMPRODUCT(–(WEEKDAY(DATE(1901,ROW(INDIRECT(”1:1200″)),1))=1)) See http://www.tushar-mehta.com/misc_tutorials/project_euler/euler019.html

  2. The code as written is examining an awful lot of irrelevant dates, since we only want the first of each month. Changing the loop to

    If Weekday(Start) = vbSunday Then
    Answer = Answer + 1
    End If
    Start = DateSerial(Year(Start), Month(Start) + 1, 1)

    is about 20 times faster on my machine (0.001875 vs 0.035625). Not 30-odd, I imagine, because the DateSerial business is more expensive than incrementing.

  3. Michael says:

    Tushar -

    Do you have a link on your website to your large arithmetic functions?

    Happy New Year!

    …mrt

  4. [...] the other hand, VBA has the edge on problem 19. I spotted a little optimisation in Michael’s code, which gave me this in VBA, which is about 20 times faster at 0.0019 seconds than the [...]

  5. Hans Schraven says:

    What about:

    For j = 0 To 1200
      If Format(DateAdd("m", j, "01-01-1900"), "w") = 1 Then x = x + 1
    Next

Leave a Reply