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