Sunday Times Teaser 2964 – “Bingo a Go-Go” Lingo a No-Go
by Stephen Hogg
Published July 14 2019 (link)
My rest home’s Bingo set uses numbers 1 to 99. To win, nine numbers on your game card must be called. Our caller, not knowing “bingo-lingo”, says “Number 1, total factors 1”, “Number 11, total factors 2” and “Number 30, total factors 8”, etc.
Yesterday, in one game, my hearing aid howled whenever a call started. I missed each number, but heard each “total factors” value. Fortunately, after just nine calls I shouted “HOUSE!” certain that I’d won.
I told my daughter how many different “factor” values I’d heard, but didn’t say what any of the values were. Knowing that I had won after nine calls, she could then be sure about some (fewer than nine) of my winning numbers.
Give, in ascending order, the numbers that she could be sure about?
-
Brian Gladman permalink12345678910111213141516171819202122232425262728293031323334353637383940from collections import defaultdictfrom itertools import chain, combinationsfrom number_theory import tau# itertools recipe for the set of subsetsdef powerset(s):return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))# group the numbers 1..99 according to their number of factorsnf2n = defaultdict(list)for n in range(1, 99):nf2n[tau(n)].append(n)# factor groups with more than nine numbers cannot participate because# the listener cannot know which of them has been calledprint("Factor Groups:")for nf in sorted(nf2n.keys()):if len(nf2n[nf]) > 9:del nf2n[nf]else:print(f"{nf:2}: {sorted(nf2n[nf])}")# find combinations of factor groups that contain exactly nine numbers# in total and store these based on the number of factor groups usedprint("\nFactor Group Combinations -> Nine Numbers:")nfg2n = defaultdict(list)for sb in powerset(nf2n.keys()):nbrs = sum((nf2n[s] for s in sb), [])if len(nbrs) == 9:nfg2n[len(sb)].append(nbrs)print(f"{len(sb):2}: {sorted(sb)} -> {sorted(nbrs)}")# find numbers that are common to all number lists that# employ the same number of factor groupsfor n0, *r in nfg2n.values():cs = set(n0).intersection(*r)if 0 < len(cs) < 9:print(f"\nSolution: {sorted(cs)}")