Sunday Times Teaser 2733 – Letter Writing
by Victor Bryant
Published: 8 February 2015 (link)
Last year I went to calligraphy lessons. They were held weekly, on the same day each week, for nine consecutive months. Actually I only went to 15 of the lessons, and after the course was over I listed the dates of those lessons that I had attended. In order to practise my new skills I wrote the dates in words (in the format “First of January” etc) and I found to my surprise that each date used a different number of letters.
What were the dates of the first and last lessons that I attended?
One Comment
Leave one →
-
Brian Gladman permalink12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758from datetime import date, timedeltafrom collections import defaultdictfrom itertools import combinations, count, product# the number of characters in each month as a wordmonth_len = [len(w) for w in ('', 'January', 'February','March', 'April', 'May', 'June', 'July', 'August','September', 'October', 'November', 'December')]# the number of characters in each day as a wordday_len = [len(w) for w in ('', 'First', 'Second', 'Third','Fourth', 'Fifth', 'Sixth', 'Seventh', 'Eighth', 'Ninth', 'Tenth','Eleventh', 'Twelfth', 'Thirteenth', 'Fourteenth', 'Fifteenth','Sixteenth', 'Seventeenth', 'Eighteenth', 'Nineteenth', 'Twentieth','TwentyFirst', 'TwentySecond', 'TwentyThird', 'TwentyFourth','TwentyFifth', 'TwentySixth', 'TwentySeventh', 'TwentyEighth','TwentyNinth', 'Thirtieth', 'ThirtyFirst')]# 'se_dates' saves the dates of the first and last lessons attendedse_dates = set()for i in count():# 'start' is the date of the first lesson in the yearstart = date(2014, 1, 1) + timedelta(days = i)# finish if the first lesson is in May (because nine# consecutive months in 2014 are no longer possible)if start.month == 5:break# collect all dates for each different word lengthdates = defaultdict(list)# move forward over nine months, a week at a timet = startwhile t.month < start.month + 9 and t.year == start.year:# add the date to the dictionary indexed on its word lengthdates[month_len[t.month] + day_len[t.day]].append(t.toordinal())t += timedelta(days = 7)# we need fifteen or more different word lengthsif len(dates) < 15:continue# output the dates for each word lengthfor lnth in sorted(dates, key=lambda x: dates[x]):print('{:02d} {}'.format(lnth,[date.fromordinal(x).strftime('%d-%b') for x in dates[lnth]]))# check all combinations of 15 lengthsfor lnths in combinations(dates, 15):# and consider all date combinations that resultfor days in product(*(dates[x] for x in lnths)):# store the first and last dates for lessons attendedse_dates.add((min(days), max(days)))# output first and last dates for lessons attendedfor t in sorted(se_dates):print(' and '.join(date.fromordinal(x).strftime('%B %d') for x in t))