Tagged: by: W Blackman Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 9:29 am on 16 August 2022 Permalink | Reply
    Tags: by: W Blackman   

    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's avatar

      Jim Randell 9:30 am on 16 August 2022 Permalink | Reply

      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:

      John (English + Italian) & Adèle (French + English)
      Jules (French + German) & Mary (English + French)
      Otto (German + French/English) & Gina (Italian + German)
      Nino (Italian + English/French) & Heidi (German + Italian)

      Otto and Nino’s second languages are English and French in some order.

      Like

    • GeoffR's avatar

      GeoffR 7:05 pm on 16 August 2022 Permalink | Reply

      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.

      Like

    • NigelR's avatar

      NigelR 1:42 pm on 17 August 2022 Permalink | Reply

      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()
      

      Like

    • GeoffR's avatar

      GeoffR 3:27 pm on 17 August 2022 Permalink | Reply

      @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)

      Like

    • Frits's avatar

      Frits 6:03 pm on 17 August 2022 Permalink | Reply

         
      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()
      

      Like

  • Unknown's avatar

    Jim Randell 9:25 am on 30 June 2020 Permalink | Reply
    Tags: by: W Blackman   

    Brain-Teaser 524: [Digit sums] 

    From The Sunday Times, 27th June 1971 [link]

    At a party at my friend Smith’s house recently, we were watching a rather attractive couple who were evidently enjoying each other’s company.

    “I don’t know those two”, I said, “but I should be interested to know the lady’s age”.

    “Well, I’m not the man to be explicit about that subject”, said Smith, “even though I know she’s rather proud of it. But her age is the sum of the digits in the sum of the digits in all the numbers from one to a hundred thousand inclusive”.

    “Certainly not very explicit”, I said, “but then, how old is her companion?”

    “Believe it or not”, said Smith, “but his age is the sum of the digits in the sum of the digits in all the numbers from one to a million inclusive”.

    What was the difference between their ages?

    This puzzle was originally published with no title.

    [teaser524]

     
    • Jim Randell's avatar

      Jim Randell 9:26 am on 30 June 2020 Permalink | Reply

      It is not too onerous to tackle the problem directly using Python.

      This program counts the digits in each of the required sequences. It runs in 405ms.

      Run: [ @replit ]

      from enigma import (fcompose, nsplit, irange, printf)
      
      # sum the digits in a number
      dsum = fcompose(nsplit, sum)
      
      # sum the digits of the numbers in a sequence
      dsums = lambda s: sum(map(dsum, s))
      
      # age of the lady
      a1 = dsum(dsums(irange(1, 100_000)))
      
      # age of the gentleman
      a2 = dsum(dsums(irange(1, 1_000_000)))
      
      printf("a1={a1} a2={a2}, diff={d}", d=abs(a1 - a2))
      

      Solution: They are the same age, so the difference is 0.


      But it is also fairly straightforward so solve analytically:

      If we suppose DS(k) is the sum of the digits in the integers (represented in base 10), starting from 0, that are less than k, then:

      The sum of the digits in 0 .. 9 is 45.

      DS(10^1) = 45

      If we then consider numbers from 0 .. 99, the units digits comprise 10 lots of DS(10), and the tens digits comprise another 10 lots of DS(10):

      DS(10^2) = 20 DS(10^1) = 900

      For the digits from 0 .. 999, the tens and units digits together comprise 10 lots of DS(100), and the hundreds digits comprise 100 lots of DS(10).

      DS(10^3) = 10 DS(10^2) + 100 DS(10^1) = 13,500

      Carrying on this construction we find:

      DS(10^n) = 45n × 10^(n − 1)

      (See: OEIS A034967 [ @oeis ]).

      The sums we are interested in are therefore:

      DS(10^5) = 45×5×(10^4) = 2,250,000
      DS(10^6) = 45×6×(10^5) = 27,000,000

      The extra 0 at the beginning doesn’t make any difference, but we need to add in the digits for the end points, which are both powers of 10, so only contribute an extra 1.

      So we are interested in the digit sums of 2,250,001 and 27,000,001, both of which are 10.

      So both ages are 10, and their difference is 0.

      Like

  • Unknown's avatar

    Jim Randell 9:45 am on 30 May 2019 Permalink | Reply
    Tags: by: W Blackman   

    Brain-Teaser 481: [Long Lane] 

    From The Sunday Times, 16th August 1970 [link]

    The houses in Long Lane are conventionally numbered; odd on one side, even on the other. Six of my friends, all of different professions, live there, all except Black on the same side of the road. Each man’s house has a two-digit number, and the sum of the twelve digits, which is a perfect square, equals the number of the solicitor’s house. One house, next door to Robinson, is vacant.

    Reversing the digits of the number of Robinson’s house give the number of the doctor’s house. Both numbers are primes. The two extreme numbers of the six are occupied by Jones and the dentist.

    Reversing the digits of Green’s house gives the number of the architect’s house, and the difference between the squares of these is the square of the number of journalist’s house. Smith and the stockbroker live next door to each other.

    What is the number of the vacant house? What is White’s profession? And what is the name of the stockbroker?

    This puzzle was originally published with no title.

    [teaser481]

     
    • Jim Randell's avatar

      Jim Randell 9:46 am on 30 May 2019 Permalink | Reply

      There are quite a few conditions. I started with the two conditions that deal with reversing one of the house numbers to get another number. Together these conditions give us the house numbers for two of the names and three of the jobs, so we can work out what the majority parity of the numbers is and fill out the remaining numbers appropriately.

      This Python program runs in 96ms.

      from enigma import (irange, filter2, is_prime, nreverse, is_square, subsets, flatten, printf)
      
      # select the first x in xs that satisfies f
      def select(xs, f):
        for x in xs:
          if f(x):
            return x
      
      # possible house numbers
      numbers = set(irange(10, 99))
      
      # split them into even and odd numbers
      (even, odd) = map(set, filter2(lambda n: n % 2 == 0, numbers))
      
      # complete a set of 6 house numbers
      def complete(ns):
        # count the even and odd numbers
        r0 = len(even.intersection(ns))
        r1 = len(odd.intersection(ns))
        # find the majority parity
        m = -1
        if r0 > 1: m += 1
        if r1 > 1: m += 2
        if m not in (0, 1): return
        # do we need to choose a minority number?
        for ys in subsets([odd, even][m].difference(ns), size=1 - [r1, r0][m]):
          # choose the remaining majority numbers
          for zs in subsets([even, odd][m].difference(ns), size=6 - len(ys) - len(ns)):
            s = ns.union(ys, zs)
            # sum the digits
            t = sum(flatten(divmod(n, 10) for n in s))
            # is a perfect square, and one of the numbers itself
            if not (t in s and is_square(t)): continue
            # return the candidate set
            yield (sorted(s), m, t)
      
      # consider Green's house number
      for Gre in numbers:
        # the reverse gives the number of the Architect's house
        Arc = nreverse(Gre)
        if Arc not in numbers: continue
        # and the difference between the squares
        # is the square of the number of the Journalist's house
        Jou = is_square(abs(Gre ** 2 - Arc ** 2))
        if Jou is None or Jou not in numbers: continue
      
        # Robinson's house number is a prime
        for Rob in numbers:
          if not is_prime(Rob): continue
          # and is the reverse of the Doctor's number
          Doc = nreverse(Rob)
          # which is also prime
          if not is_prime(Doc): continue
      
          # complete the set of numbers
          for (ns, m, t) in complete(set((Gre, Rob, Arc, Jou, Doc))):
            # the sum of the digits is the number of the Solicitor's house
            Sol = t
            # Black is in the minority parity house
            Bla = select(ns, (lambda n: n % 2 != m))
      
            # (at least) one of the houses next to Robinson is vacant
            vacant = set([Rob - 2, Rob + 2]).difference(ns)
            if len(vacant) < 1: continue
      
            # the extreme numbers are occupied by Jones and the Dentist
            for (Jon, Den) in subsets([ns[0], ns[-1]], size=2, permute=1):
      
              # and we now have 5 of the 6 professions
              ps = set([Arc, Jou, Doc, Sol, Den])
              if len(ps) != 5: continue
              Sto = select(ns, (lambda n: n not in ps))
      
              # and 4 of the 6 names
              ss = set([Gre, Rob, Bla, Jon])
              if len(ss) != 4: continue
              for (Smi, Whi) in subsets(ss.symmetric_difference(ns), size=2, permute=1):
      
                # Smith and the Stockbroker live next door to each other
                if not (abs(Smi - Sto) == 2): continue
      
                # output solutions
                name = { Gre: 'Green', Rob: 'Robinson', Bla: 'Black', Jon: 'Jones', Smi: 'Smith', Whi: 'White' }
                job = { Arc: 'Architect', Jou: 'Journalist', Doc: 'Doctor', Sol: 'Solicitor', Den: 'Dentist', Sto: 'Stockbroker' }
                for n in ns:
                  printf("{n}: {name} ({job})", name=name[n], job=job[n])
                printf("vacant = {vacant}", vacant=sorted(vacant))
                printf()
      

      Solution: The vacant house is number 29. White is the Solicitor. Robinson is the Stockbroker.

      The solution is completely determined:

      13: Jones (Doctor)
      31: Robinson (Stockbroker)
      33: Smith (Journalist)
      49: White (Solicitor)
      56: Black (Architect)
      65: Green (Dentist)

      29: vacant

      Like

c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Design a site like this with WordPress.com
Get started