Archive for July, 2010

Problem 19 – First Sundays

July 25, 2010

I don’t think I can state the question of problem 19 any more succinctly than the problem author:

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

I spent a few minutes perusing the datetime docs, and about an hour playing with a handful of variations on how to do this problem.

As usual, I like to start out with a stupid algorithm, just to get the right answer, so I know when other tries work. There’s not much simpler than starting on 1 Jan 1901 and adding days until you get to 31 Dec 2000, seeing when you’re on a day that’s a Sunday and the first of the month:

   count = 0
   curdate = date(1901, 1, 1)
   daydelta = timedelta(1) # 1 day
   while curdate.year < 2001:
      if curdate.weekday() == 6 and curdate.day == 1:
         count += 1
      curdate += daydelta

   print count

Of course, we’d do better to increment by weeks, so that we’re always on Sunday (as long as we start on a Sunday). Alternatively, we could increment by as many days as are in the month we’re in, but then we have to keep track of leap years. That never seems as clean, at least when I do it:

   count = 0
   daysinmonth = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
   curdate = date(1901, 1, 1)
   while curdate.year < 2001:
      if curdate.weekday() == 6:
         count += 1
      curdate += timedelta(daysinmonth[curdate.month]-1)
      if curdate.year % 4 == 0 and (curdate.year % 100 != 0 or curdate.year % 400 == 0):
         curdate += timedelta(1)

   print count

Of course, I’m generally most amused if I can solve the problem in a single line. Allowing longish lines (perhaps ‘single statement’ would be more correct)…

print len(filter(lambda d:d.weekday()==6, [date(1901,1,1).replace(month=n,year=y) for n in range(1,13) for y in range(1901,2001)]))
Advertisements