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 9:46 am on 30 May 2019 Permalink |
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:
LikeLike