Enigmatic Code

Programming Enigma Puzzles

Enigma 222: Hard astern

From New Scientist #1368, 28th July 1983 [link]

Admirals Drake, Jellicoe, Nelson and Raleigh were lately piped aboard HMS Beefeater for purposes of splicing the mainbrace. Each arrived immaculate in his well-cut uniform, did his share of the work to the full and departed with dignity barely askew. But (sh!) Drake presently realised that he had somehow come to be wearing a pair of trousers too small for him and a similarly tight feeling presently crept over Jellico. Nelson and Raleigh too found themselves clad in the wrong breeches.

Each promptly dispatched the trousers in his possession to one of the others. Each received one pair, not sent by the admiral to whom he had sent one and, alas, not his own. Nelson received a pair too tight for him.

Well, shiver my timbers, they then did the same again. Each sent off the pair in question. Each received a pair, not from the Admiral he had fired one at, not one which he had had already and still not his own. Drake received a pair too large for him, his own being now lodged with either Jellicoe or Nelson.

Who now had whose breeches?

Note: I am waiting for a phone line to be connected at my new house, so I only have sporadic access to the internet at the moment. The current estimate is that the line will be connected at the end of September 2014.


One response to “Enigma 222: Hard astern

  1. Jim Randell 15 September 2014 at 2:10 pm

    This Python program runs in 31ms.

    I assumed that the trousers (and the Admirals) are different sizes, as the only way to tell you have the wrong trousers appears to be by the fit, and they each get three different wrong pairs.

    from itertools import permutations
    from enigma import diff, printf
    # labels for the admirals
    (D, J, N, R) = (0, 1, 2, 3)
    # labels for the trousers (in size order)
    ts = (1, 2, 3, 4)
    # consider initial assignments
    for t0 in permutations(ts):
      # D will get pairs too small and too large, so is 2 or 3
      # J gets a pair too small, so is 2, 3 or 4
      if t0[D] in (1, 4) or t0[J] == 1: continue
      # choose the first assignment of trousers
      for t1 in permutations(t0):
        # D and J have trousers too small
        # N and R have the wrong trousers
        if not(t1[D] < t0[D] and t1[J] < t0[J] and t1[N] != t0[N] and t1[R] != t0[R]): continue
        # choose the second assigment of trousers
        for t2 in permutations(t0):
          # N has a pair too tight, no-one has the right pair
          if not(t2[D] != t0[D] and t2[J] != t0[J] and t2[N] < t0[N] and t2[R] != t0[R]): continue
          # no-one has the same pair as before
          if any(x == y for (x, y) in zip(t1, t2)): continue
          # no-one swaps pairs with someone else
          if any(t1[t2.index(t)] == t2[i] for (i, t) in enumerate(t1)): continue
          # in the third assignment each gets the remaining pair of incorrect trousers
          t3 = tuple(diff(t0, (t0[p], t1[p], t2[p]))[0] for p in (D, J, N, R))
          # D has a pair too large, his own being with J or N
          if not(t3[D] > t0[D] and t0[D] in (t3[J], t3[N])): continue
          # but no-one swaps pairs with someone else
          if any(t2[t3.index(t)] == t3[i] for (i, t) in enumerate(t2)): continue
          printf("[{t0} => {t1} => {t2} => {t3}]")
          s = 'DJNR'
          print(', '.join(p + ' has ' +  s[t0.index(t3[i])] + '\'s' for (p, i) in zip(s, (D, J, N, R))))

    Solution: Drake has Nelson’s; Jellicoe has Drake’s; Nelson has Raleigh’s; Raleigh has Jellicoe’s.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: