Brain-Teaser 161: 100-yard race
From The Sunday Times, 10th May 1964 [link]
Harry, Kenneth, Lionel, Martin, Nicholas and Oliver were, the competitors in the 100-yard race on Sports Day. They wore cards numbered 1, 2, 3, 4, 5, 6 but not in that order. In no case was the position of any of the competitors the same as his card number but two of the competitors had positions equal to each other’s card number.
Nicholas was 5th and his card number was the same as Kenneth’s position. Harry’s card number was the same as Oliver’s position which was 4th. Martin’s card number was 1.
It was found that the sum of the products of each competitor’s position and card number was 61.
Place the competitors in the order in which they finished the race and give their card numbers.
This puzzle is included in the book Sunday Times Brain Teasers (1974).
[teaser161]













Jim Randell 11:57 am on 31 July 2022 Permalink |
This Python program runs in 56ms. (Internal run time is 1.3ms).
Run: [ @replit ]
from enigma import (irange, subsets, reverse, diff, singleton, printf) pos = list(irange(1, 6)) # consider the cards in each position (1st, ..., 6th) for ps in subsets(pos, size=6, select="D"): # card: map pos -> card card = dict(enumerate(ps, start=1)) # the sum of the position/card products is 61 if sum(i * p for (i, p) in card.items()) != 61: continue # there is (at least) one 2-cycle if not any(card[p] == i for (i, p) in card.items()): continue # name: map pos -> name # "N was 5th" # "O was 4th" # "K's position is N's card number (N is 5th)" # "H's card number is O's position (O is 4th)" # "M's card number is 1" # so we have enough information to fill out the map rcard = reverse(card) ks = [5, 4, card[5], rcard[4], rcard[1]] ks.append(singleton(diff(pos, ks))) if ks[-1] is None: continue name = dict(zip(ks, "NOKHML")) # check disallowed order if all(name[i] == x for (i, x) in zip(pos, "HKLMNO")): continue # output solution for i in pos: printf("{i}: {n} = #{c}", c=card[i], n=name[i]) printf()Solution: The finishing positions are:
LikeLike
Frits 11:53 am on 3 August 2022 Permalink |
from enigma import SubstitutedExpression # get position from card number pos = lambda n, lst: [i for i, x in enumerate(lst, start=1) if x == n][0] l1 = "[A, B, C, D, E, F]" # card numbers l2 = "[1, 2, 3, 4, 5, 6], " + l1 # positions and card numbers z = "zip(" + l2 + ")" exprs = [] # position unequal to card number for all competitors exprs.append("all(x != y for x, y in " + z + ")") # sum of the products of each competitor's position and card number was 61 exprs.append("sum(x * y for x, y in " + z + ") == 61") # two of the competitors had positions equal to each other's card number exprs.append("sum((y, x) in " + z + " for x, y in " + z + ") == 2") # M ( , 1) # N (5, x) # O (4, ) # H ( , 4) # K (x, ) # L ( , ) # check on five different positions exprs.append("len({pos(1, " + l1 + "), pos(4, " + l1 + "), E, 4, 5}) == 5") # the alphametic puzzle p = SubstitutedExpression( exprs, answer="((1, A), (2, B), (3, C), (4, D), (5, E), (6, F))", digits=range(1, 7), distinct=("ABCDEF"), env=dict(pos=pos), verbose=0, # use 256 to see the generated code ) names = ["", "", "", "Oliver", "Nicholas", ""] for (_, ans) in p.solve(): # dictionary, card --> postion d = {y: x for x, y in ans} names[d[1] - 1] = "Martin" names[d[4] - 1] = "Harry" names[ans[4][1] - 1] = "Kenneth" for i in range(6): if names[i] == "": names[i] = "Lionel" # integrity check if len(set(names)) != 6: continue for i in range(6): print(f"{ans[i][0]}: {names[i]} with card number {ans[i][1]}")LikeLike