Brain-Teaser 732: … a Frenchman, an Italian, …
From The Sunday Times, 27th July 1975 [link]
The staff of a certain international organisation, in their day-to-day work, use four languages — English, French, German and Italian — and every employee is required to be fluent in two of them, viz. his or her own, and one of the other three.
The four heads of branches of the Circumlocution Division are of different nationalities; their second languages are also all different. Each has a woman secretary whose second language is the native language of her chief, but in no case is either language of the chief the native language of his secretary.
All eight are colleagues of mine. John and Mary are English, Jules and Adèle French, Otto and Heidi German, and Nino and Gina Italian.
The man of the same nationality as John’s secretary has German as his second language.
The secretary of the man whose native language is Jules’s second language is of the same nationality as Heidi’s chief.
Who is Jules’s secretary? And which man has Italian as his second language?
This puzzle is included in the book The Sunday Times Book of Brain-Teasers: Book 2 (1981).
[teaser732]
Jim Randell 9:30 am on 16 August 2022 Permalink |
This Python program runs in 58ms. (Internal run time is 649µs).
Run: [ @replit ]
from enigma import (subsets, update, singleton, map2str, printf) # languages (English, French, German, Italian) langs = ['en', 'fr', 'de', 'it'] # chiefs and secretaries (in language order) chiefs = ['John', 'Jules', 'Otto', 'Nino'] secs = ['Mary', 'Adele', 'Heidi', 'Gina'] # lang1: map names to first languages lang1 = dict(zip(chiefs + secs, langs + langs)) # nat: map first language (nationality) to chief nat = dict(zip(langs, chiefs)) # sec: maps chief -> secretary # chief: maps secretary -> chief for ss in subsets(secs, size=len, select="P"): sec = dict(zip(chiefs, ss)) chief = dict(zip(ss, chiefs)) # chiefs and secretaries do not share first languages if any(lang1[k] == lang1[v] for (k, v) in sec.items()): continue # lang2: map names to second languages # the second language of the secretary is the first language of the chief lang2a = dict((v, lang1[k]) for (k, v) in sec.items()) # assign second languages to the chiefs (different from first languages) for vs in subsets(langs, size=len, select="D"): lang2 = update(lang2a, chiefs, vs) # the second language of the chief is not the first language of the secretary if any(lang2[k] == lang1[v] for (k, v) in sec.items()): continue # check conditions: # "The man of the same nationality as John's secretary, has German as his second language" if not (lang2[nat[lang1[sec['John']]]] == 'de'): continue # "The secretary of the man whose native language is Jules's # second language is of the same nationality as Heidi's chief" if not (lang1[sec[nat[lang2['Jules']]]] == lang1[chief['Heidi']]): continue # output solution(s), and maps printf("sec[Jules] = {x}; lang2[{y}] = it", x=sec['Jules'], y=singleton(y for y in chiefs if lang2[y] == 'it')) printf("-> sec = {sec}", sec=map2str(sec, sort=0)) printf("-> lang2 = {lang2}", lang2=map2str(lang2, sort=0)) printf()Solution: Mary is Jules’ secretary. John has Italian as a second language.
The complete assignments are:
Otto and Nino’s second languages are English and French in some order.
LikeLike
GeoffR 7:05 pm on 16 August 2022 Permalink |
Circumlocution looks like an interesting reference to Charles Dickens.
The Circumlocution Office, a fictitious governmental department featured in the Charles Dickens novel Little Dorrit. Dickens took an existing word in the English language, circumlocution, and applied it to satirise that department.
The word circumlocution describes the use of an unnecessarily amount of words to get to the point, where just a few would do.
LikeLike
NigelR 1:42 pm on 17 August 2022 Permalink |
I think I now need a lie down with a cold towel round my head after keeping track of nested dictionaries! For some reason my shell (Thonny) crashes when I run the enigma timer.
from itertools import permutations as perm #timer.start() def test(): y=[z for z in Chiefs if Chiefs[z][0]==Chiefs['Jules'][1]][0] #Chief with nat of Jules 2nd lang (aka y) #y's secretary is [Chiefs[y][2]] and her nationality is Secs[Chiefs[y][2]][0]) for x in Chiefs: if Secs[Chiefs[x][2]][0]==Chiefs[x][0]:return False #check Sec native lang against chief nat. if Secs[Chiefs[x][2]][1]!=Chiefs[x][0]:return False # check Sec 2nd is chief's nat if Chiefs[x][0] == Secs[Chiefs[x][2]][0] or Chiefs[x][1] == Secs[Chiefs[x][2]][0]:return False # check neither sec lang is chief's nat #The man of the same nationality as John’s secretary has German as his second language if Chiefs[x][0]==Secs[Chiefs['John'][2]][0] and Chiefs[x][1]!='Ge':return False #The secretary of the man whose native language is Jules’s second language is of the same nationality as Heidi’s chief if Chiefs[x][2]=='Heidi' and Secs[Chiefs[y][2]][0]!=Chiefs[x][0]:return False return True Chief = ['John','Jules','Otto','Nino'] Sec = ['Mary','Adele','Heidi','Gina'] Nat = ['En','Fr','Ge','It'] Chiefs={Chief[i]:[Nat[i],0,0] for i in range(4)} Secs = {Sec[i]:[Nat[i],0] for i in range(4)} for Clang in perm(Nat): #generate second languages for Chiefs for i, x in enumerate(Chiefs): Chiefs[x][1] = Clang[i] if any([i for i in Chiefs if Chiefs[i][0]==Chiefs[i][1]]):continue # second lang cannot be same as first for Slang in perm(Nat): #generate second language for secretaries for i, x in enumerate(Secs): Secs[x][1] = Slang[i] if any([i for i in Secs if Secs[i][0]==Secs[i][1]]): continue # second lang cannot be same as first for Sal in perm(Secs): for i , x in enumerate(Chiefs): Chiefs[x][2] = Sal[i] #allocate secretaries to chiefs if not test():continue #Who is Jules’s secretary? And which man has Italian as his second language? I2l = [i for i in Chiefs if Chiefs[i][1]=='It'][0] print('Jules secretary is', Chiefs['Jules'][2],'.', I2l, 'has Italian as second language' ) print (Chiefs) #timer.stop() #timer.report()LikeLike
GeoffR 3:27 pm on 17 August 2022 Permalink |
@NigelR:
Excellent work.
I added ‘from enigma import timer’ to your code after the permutation import. (Before timer.start() )
This worked OK for me in the Idle interface
[timing] total time: 0.0838237s (83.82ms)
LikeLike
Frits 6:03 pm on 17 August 2022 Permalink |
from itertools import product # languages (English, French, German, Italian) langs = ['en', 'fr', 'de', 'it'] # chiefs and secretaries (in language order) chiefs = ['John', 'Jules', 'Otto', 'Nino'] secs = ['Mary', 'Adele', 'Heidi', 'Gina'] # options per chief lst = [[] for _ in range(4)] # generate all combinations of chief, secretary and chief's second language for chf, sec, c_lang_2 in product(*[chiefs, secs, langs]): chf_i = chiefs.index(chf) c_lang_1 = langs[chf_i] s_lang_1, s_lang_2 = langs[secs.index(sec)], c_lang_1 # in no case is either language of the chief # the native language of his secretary if c_lang_1 == c_lang_2 or s_lang_1 == s_lang_2 or \ s_lang_1 in {c_lang_1, c_lang_2}: continue lst[chf_i].append([c_lang_1, c_lang_2, sec, s_lang_1, s_lang_2]) # check all combinations of options per chief for p in product(*lst): # chiefs have different secretaries and ... if len(set(chf[2] for chf in p)) != 4: continue # ... their second languages are also all different if len(set(chf[1] for chf in p)) != 4: continue Jo, Ju, _, _ = p # the man of the same nationality as # John's secretary has German as his second language if [chf for chf in p[1:] if chf[0] == Jo[3]][0][1] != 'de': continue # The secretary of the man whose native language # is Jules's second language is of the same nationality as Heidi's chief lang_sec = [chf[3] for i, chf in enumerate(p) if i != 1 and chf[0] == Ju[1]][0] lang_chf_H = [chf[0] for chf in p if chf[2] == 'Heidi'][0] if lang_sec != lang_chf_H: continue for z in zip(chiefs, p): print(z) print(f"Jules' secretary: {Ju[2]}, John's second language: {Jo[1]}") print()LikeLike