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)?

‘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

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

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

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.

Tushar –

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

Happy New Year!

…mrt

[…] 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 […]

What about:

If Format(DateAdd(“m”, j, “01-01-1900”), “w”) = 1 Then x = x + 1

Next