Sunday Times Teaser 2506 – No Title
by Quentin Fowler
Published October 4 2010 (link)
Three brothers share a house in a university city. Each is capable of undertaking two of the four domestic chores required. For instance, only one knows how to vacuum and only one can dust. They have recruited two friends who can do three chores each, so now any chore can be done by three people. Leo does not wash up; in fact, only one person can both wash up and do the laundry. There is one job both Leo and Neil can do, while Keith and Neil can do two jobs together. John can vacuum; Mike cannot. Neil is one of the brothers.
Who are the other two brothers, and who does the dusting?
One Comment
Leave one →
-
Brian Gladman permalink123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566from itertools import combinations, productfrom collections import defaultdict# dictionary of boy's names indexed on their first letterboys = {c[0]:c for c in 'John Keith Leo Mike Neil'.split()}# dictionary of chore names indexed on their first letterchores = {c[0]:c for c in 'Dust Launder Vacuum Wash'.split()}# a tuple of pairs of choresch_p = tuple(''.join(x) for x in combinations(chores, 2))# a tuple of triples of choresch_t = tuple(''.join(x) for x in combinations(chores, 3))# consider possible combinations for the brothersfor a, b, c in combinations(boys, 3):# the friendsd, e = sorted(set(boys).difference((a, b, c)))# Neil is one of the brothersif 'N' not in {a, b, c}:continue# their brothers possible pairs of choresfor ca, cb, cc in product(ch_p, repeat=3):# map the boys to their choresb2c = dict(zip((a, b, c), (ca, cb, cc)))# only one can vacuum and only one can dustt = ''.join(b2c.values())if not (t.count('V') == t.count('D') == 1):continue# consider the possible triples of the friends choresfor cd, ce in product(ch_t, repeat=2):# update the map of the boys choresb2c.update(zip((d, e), (cd, ce)))# create a map from chores to the boys who can do themc2b = defaultdict(set)for boy in b2c.keys():for chore in b2c[boy]:c2b[chore].add(boy)# all boys can do three choresif not all(len(c2b[ch]) >= 3 for ch in c2b.keys()):continue# Leo does not wash upif 'W' in b2c['L']:continue# only one person can wash and launderwl_cnt = sum(1 for b in b2c.keys() if {'W', 'L'} <= set(b2c[b]))if wl_cnt != 1:continue# Leo and Neil can share one choreif len(set(b2c['L']).intersection(b2c['N'])) != 1:continue# Keith and Neil can share two choresif len(set(b2c['K']).intersection(b2c['N'])) != 2:continue# John can vacuum but Mike can'tif 'V' not in b2c['J'] or 'V' in b2c['M']:continuefor i, boy in enumerate((a, b, c, d, e)):t = boys[boy] + (' (brother):' if i < 3 else ' (friend):')print(f"{t:15} {', '.join(chores[c] for c in b2c[boy])}")