Su Mo Tu We Th Fr Sa

1 2

3 4 5 6 7 8 9

10 11 12 13 14 15 16

17 18 19 20 21 22 23

24 25 26 27 28 29 30

31

You can see pretty easily from this, that a) we'll have the five Fr/Sa/Su anytime we start October on a Friday and b) no other configuration will have this. Now just thinking about this off the top of my head, I figured that this should happen about ever 7 years (disregarding leap years).

Now as it happens, I'd also just finished a short ruby method for Zeller's Congruence that I'd written from an article on Programming Praxis. So, I combined the two and came up with the following ...

# Zeller’s Congruence is a simple mathematical method for determining the day

# of the week for a given date.

#

# In the 1880s, Christian Zeller, a German mathematician, noticed that, if you

# run a year from March through February, the cumulative number of days in each

# month forms a nearly straight line; that works because February, which would

# normally perturb the straight line, is moved to the end. He worked out the

# formula ⌊(13m−1)/5⌋ to give the number of weekdays that the start of the

# month moves each month, where m is the month number.

#

# Then it is easy to calculate the day of the week for any given day: add the

# day of the month, the offset for the number of months since March, an offset

# for each year, and additional offsets for leap years and leap centuries

# (remembering to subtract one year for dates in January and February), taking

# the whole thing mod 7. It’s fun to work out the arithmetic yourself, but if

# you don’t want to take the time, the whole formula is shown in the solution.

#

# Your task is to write a function that uses Zeller’s Congruence to calculate

# the day of the week for any given date. When you are finished, you are

# welcome to read or run a suggested solution, or to post your own solution or

# discuss the exercise in the comments below.#

#

# f = k + floor(13m - 1) / 5) + d + floor(d / 4) + floor(c / 4) - 2c mod 7

#

# Su Mo Tu We Th Fr Sa

# 1 2

# 3 4 5 6 7 8 9

# 10 11 12 13 14 15 16

# 17 18 19 20 21 22 23

# 24 25 26 27 28 29 30

# 31

#

#

#

def zeller(year, month, day)

months = %w[march april may june july august september october november december january february]

weekdays = %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]

k = day

m = months.index(month.downcase) + 1

y = (m <= 10) ? year : year-1

d = y % 100

c = y / 100

f = (k + (((13*m) - 1) / 5).floor + d + (d/4).floor + (c/4).floor - (2*c)) % 7

weekdays[f]

end

1900.upto(2300) do |y|

puts "Five Friday, Saturday, and Sundays for October, #{y}" if zeller(y, "october", 1) == "Friday"

end

Here, we'll just go through the years from 1900 to 2300 or about 400 years and see how many times the five Fr/Sa/Su pattern occurs. If we run this and pipe it through

`wc -l`

, we end up with `56`

. Interestingly enough, 400 / 7 is 57 which is what we originally calculated above ignoring the leap years.Let me know if you have any questions or comments.

## No comments:

## Post a Comment