Enigmatic Code

Programming Enigma Puzzles

Enigma 211: How’s that

From New Scientist #1357, 12th May 1983 [link]

The last ball was bowled; the stumps were drawn; and the epic cricket contest between All-Muggleton and Dingley Dell was over for another year. The twenty-two players determined to adjourn to a near-by tavern for refreshment. But they could by no means agree as to which of the four adjacent taverns was most deserving of their favour. At length Mr Pickwick proposed that each player should visit whichever two of the four establishments should best take his fancy; and so it was resolved.

In the ensuing hour just 11 players presented themselves at the Angler, just 11 at the Bull, just 11 at the Crow and just 11 at the Drum. The number who dropped in at both the Angler and the Bull was double the number who imbibed at both the Angler and the Crow and was not surpassed by the number of those who chose any other pair of taverns, which you can mention.

Afterwards it occurred to Mr Winkle to wonder how many players had availed themselves of both the Crow and the Drum. The company was by then too far advanced in high spirits to hit on the right answer and it was agreed to present the problem to you.

[enigma211]

Advertisements

3 responses to “Enigma 211: How’s that

  1. Jim Randell 2 August 2014 at 8:20 am

    This Python 3 program runs in 50ms.

    from enigma import irange, printf
    
    # let AB, AC, AD, BC, BD, CD denote the number of players that visited
    # a particular pair of pubs. Then:
    #
    # AB + AC + AD = 11
    # AB + BC + BD = 11
    # AC + BC + CD = 11
    # AD + BD + CD = 11
    
    # decompose n into m numbers (1 or larger)
    def decompose(n, m, s=[]):
      if m == 1:
        yield s + [n]
      else:
        for x in irange(1, n - 1):
          yield from decompose(n - x, m - 1, s + [x])
    
    # for A
    for (AB, AC, AD) in decompose(11, 3):
      # AB = 2AC, AB >= AD
      if not(AB == 2 * AC and AB >= AD): continue
    
      # for B
      for (BC, BD) in decompose(11 - AB, 2):
        if BC > AB or BD > AB: continue
    
        # for C
        CD = 11 - (AC + BC)
        if CD > AB: continue
    
        # for D
        if AD + BD + CD != 11: continue
    
        printf("AB={AB} AC={AC} AD={AD} BC={BC} BD={BD} CD={CD}")
    

    Solution: 6 players visited both the Crow and the Drum.

  2. arthurvause 12 August 2014 at 8:36 pm

    Using sympy to solve the set of simultaneous equations:

    from sympy import solve, Symbol,var
    
    var('AD  BC  BD  CD')
    n=Symbol('n')
    
    for n in xrange(1,4):
      s = solve([3*n + AD - 11,
                 2*n + BC + BD - 11,
                 n + BC + CD - 11,
                 AD + BD + CD - 11], [AD,  BC,  BD,  CD])
      if max(s[x] for x in s) <= 2*n:
        print s[CD],'players visited the Crow and Drum'
    
  3. Jim Randell 13 August 2014 at 12:56 pm

    Or using PyMathProg:

    import pymprog
    from enigma import printf
    
    p = pymprog.model('enigma211')
    
    (AB, AC, AD, BC, BD, CD) = (p.var(name=x, kind=int, bounds=(0, 11)) for x in ('AB', 'AC', 'AD', 'BC', 'BD', 'CD'))
    
    p.st(AB + AC + AD == 11)
    p.st(AB + BC + BD == 11)
    p.st(AC + BC + CD == 11)
    p.st(AD + BD + CD == 11)
    
    p.st(AB == 2 * AC)
    p.st(AB >= AD)
    p.st(AB >= BC)
    p.st(AB >= BD)
    p.st(AB >= CD)
    
    p.solve(int)
    
    printf("AB={AB.primal:.0f} AC={AC.primal:.0f} AD={AD.primal:.0f} BC={BC.primal:.0f} BD={BD.primal:.0f} CD={CD.primal:.0f}")
    

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: