Here’s a puzzle for you -

You own a time machine with an unusual property: it can only travel to 29^{th} February. It can jump to any 29th February, anywhere at all, in any year (even back before we invented the Gregorian Calendar, and far into the future after we’ve stopped using it), but it can only finish its journey on a 29^{th} of February, in a Gregorian leap year (for this reason, it can only jump to years which are leap years).

One day, you decide to take it for a spin. So you get into your time machine and press the “random” button. Moments later, you have arrived: it is now 29^{th} February in a random year!

Without knowing what year it is: what is the probability that it is a Monday? (hint: the answer is *not* ^{1}/_{7} – half of your challenge is to work out why!).

**Warning:**comments may contain the answer.

## By Gareth 24 September, 2012 - 17:44

The chance is the same as it being a Wednesday or a Friday (which are the most probable) and it’s least likely to be Tuesday, but as you say, interesting to learn

why(hence I’m not saying any more!)## By Scatman Dan 24 September, 2012 - 19:16

That’s interesting. I suspect we’re thinking in the same direction, but I didn’t quite get the same answer. What’s the probability you calculate for Monday?

I’ll post my answer (and how I worked it out, in case I’m wrong!) later in the week.

## By Gareth 25 September, 2012 - 11:54

Hm, so I made a “small” mistake in my calculations due to changing from using the Date class to Time in Ruby and it not throwing an exception I was expecting… Grr.

Having fixed that (and done a sanity check!), I now get Monday and Wednesday having the same (highest) probability, of 15/97, or 0.15463917525773196. I’ll send you my code :-)

## By Scatman Dan 25 September, 2012 - 11:57

Nicely done. That’s my answer, too. Here’s my code (also in Ruby):

`puts (0..400).`

collect{|i|Time::new(i,2,29)}.

reject{|t|t.day==1}.

collect{|t|t.strftime('%a')}.

group_by{|d|d}.

collect{|k,v|[k,v.length]}.

sort_by{|k,v|v}.reverse.

collect{|k,v|"%s - %d"%[k,v]}.

join("\n")

It’s a little sloppy: I could have taken some more-elegant shortcuts.

## By Gareth 25 September, 2012 - 12:44

It’s also broken ;-)

Your code is checking 401 years (between the year 0 and the year 400, inclusive)

Changing 0..400 to 0…400 would do the right thing.

## By Scatman Dan 25 September, 2012 - 15:00

Ah-hah! Right you are. I’m still correct for the ranges I tested (because the year after and the year before aren’t leap years anyway), but it’s a valid point. I had meant to use:

(0…400)

## By Gareth 25 September, 2012 - 16:23

The year 0 and the year 400 are *both* leap years, so your code added an extra Leap-Tuesday into the mix.

## By Scatman Dan 25 September, 2012 - 16:32

You’re right that my code makes that mistake. However the fact that it comes up with the wrong answer as a result could be a fault of the interpreter and not my code…

The year “0″ in ISO 8601 format, as (supposedly) used by Ruby’s Date format, corresponds to 1BCE (there was no “year 0″ as zero hadn’t come to the West at the time of the creation of the Gregorian calendar). Should this be a leap year? It depends on how you calculate them. It’s four years from a leap year and not the 25th such leap year in a row (and not-not the 100th potential one), which would say yes. But on the other hand, it doesn’t divide by 4, which would say no.

…or rather, it’s the fact that there is no unambiguous definition in the Gregorian calendar about how to handle BCE leap years that means that different interpretations exist. It could be argued either way whether 1BCE was a leap year or not. Ruby says it was, but I’m not sure it’s right…

## By iamapizza 25 September, 2012 - 14:17

Also replied on Reddit:

import collections

def getDayFromNumber(n):

if n == 0:

return 'Tuesday'

if n == 1:

return 'Monday'

if n == 2:

return 'Sunday'

if n == 3:

return 'Saturday'

if n == 4:

return 'Friday'

if n == 5:

return 'Thursday'

if n == 6:

return 'Wednesday'

yearDay = {}

days = []

centuryCounter = 0

for y in range(1600,1999):

if y > 1600 and y % 100 == 0:

centuryCounter = centuryCounter + 1

if y % 1600 == 0 or (y % 4 == 0 and not y % 100 == 0):

d = (((y-1600) / 2) + centuryCounter) % 7

yearDay[y] = getDayFromNumber(d)

days.append(getDayFromNumber(d))

`print yearDay`

print collections.Counter(days)

## By Spencer 27 September, 2012 - 22:37

This problem is fairly easy to solve if you know about Conway’s “Doomsday Rule” for converting dates to days of the week in your head.

Following Conway’s Doomsday rule, the last day of Feb is always a doomsday. So then we have do calculate the distribution of doomsdays for the 400-year gregorian cycle. This is done nicely with the code above; I just counted from Wikipedia’s list of Doomsdays, which conveniently highlights leap-years.

Mon 15

Tue 13

Wed 15

Thu 13

Fri 14

Sat 14

Sun 13

Total 97

## By Scatman Dan 27 September, 2012 - 22:42

What an excellent way to get to the answer!