Sunday Times Teaser 2562 – Chez Nous
Published: 30 October 2011 (link)
A sign-writer stocks signs of house numbers written in words, from “one” up to my own house number. The signs are kept in boxes according to the number of letters used. Eg, all copies of “seven” and “fifty” are in the same box. Each box contains at least two different signs. Boxes are labelled showing the number of letters used, eg the box holding “fifty” is labelled “five”. Naturally, the sign-writer has used signs from his own stock for the labels. To label all the boxes he needed to take signs from half of the boxes.
What is my house number?
One Comment
Leave one →
-
Brian Gladman permalink1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162from itertools import countfrom collections import defaultdictones = ( '', 'one', 'two', 'three', 'four', 'five','six', 'seven', 'eight', 'nine' )tens = ( '', '', 'twenty', 'thirty', 'forty', 'fifty','sixty', 'seventy', 'eighty', 'ninety' )teen = ( 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen','fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' )# turn a number (less than 1000) into its text formdef nbr_as_text(n):if n >= 1000:raise ValueErrors = []if n >= 100:h, n = divmod(n, 100)s += [ones[h] + ' hundred' + (' and' if n else '')]if n >= 20:s += [tens[n // 10]]n %= 10if 10 <= n:s += [teen[n - 10]]else:s += [ones[n % 10]]return ' '.join(s)# the boxes labelled with the length of the signs they holdboxes = defaultdict(set)# the lengths of box labelslabel_lengths = set()# consider increasing numbers from one upwardsfor nbr in count(1):# find which box this sign goes in and add itlnth = len(nbr_as_text(nbr).replace(' ', ''))boxes[lnth].add(nbr)# now consider the label for this boxlabel_len = len(nbr_as_text(lnth).replace(' ', ''))# add it to the box this label goes inboxes[label_len].add(lnth)# record it as a box labellabel_lengths.add(label_len)# ensure all boxes hold at least two signsif all(len(x) > 1 for x in boxes.values()):# check if the number of labels is equal to# half the number of boxesif 2 * len(label_lengths) == len(boxes):# the example is supposed to be real so the# house number must be at least fiftyif nbr >= 50:print('The house number is {}.'.format(nbr))break