Enigmatic Code

Programming Enigma Puzzles

Enigma 236: Men on a bummel

From New Scientist #1382, 3rd November 1983 [link]

On the last night of their German holiday, Amble, Bumble, Crumble and Dimwit ate at Das Goldene Rätsel, famous for its Anglo-German cuisine. Each had one dish from each course. Here is the menu.

Enigma 236

Dimwit is, alas, now recovering from food poisoning and too ill to recall what he ate or spent. Nor can the others recall, but the three spent the same amount each and know what each of the three ate. Making the reasonable assumption that Dimwit was done for by something he alone chose, they have deduced what the offending dish must have been.

Can you do the same?

Coincidentally, I am currently reading Jerome K. Jerome‘s “Three Men on the Bummel“.

Note: I now have a phone line installed at my new house, but I’m waiting for ADSL to be activated on it, so I only have sporadic access to the internet at the moment. The current estimate is that I should have an internet connection next week.



One response to “Enigma 236: Men on a bummel

  1. Jim Randell 9 November 2014 at 7:29 am

    This Python 3 program runs in 50ms.

    # A, B and C must have consumed 8 of the dishes between them (in order
    # to be able to determine the remaining dish that poisoned D), so
    # exactly one of the dishes is shared between 2 of them
    from itertools import permutations, product
    from enigma import irange, uniq, flatten, printf
    # the dishes (the dishes in each course can be distinguished by price)
    courses = ([2, 4, 5], [4, 8, 10], [3, 5, 7])
    # total price of all dishes on the menu
    total = sum(flatten(courses))
    # return a copy of <s> with the first <x> removed
    def remove(s, x):
      # if list.remove() returned the list this would just be: [[ return list(s).remove(x) ]]
      s = list(s)
      return s
    # choose a dish from each course, so the total sums to s
    # return (<dishes chosen>, <remaining dishes in each course>)
    def dishes(courses, s):
      # is there only one course?
      if len(courses) == 1:
        # is there a dish of the required price?
        if s in courses[0]:
          yield ([s], [remove(courses[0], s)])
        # consider possible dishes from the first course
        for d in uniq(courses[0]):
          if not(d < s): continue
          # choose the remaining courses
          for (ds, cs) in dishes(courses[1:], s - d):
            yield ([d] + ds, [remove(courses[0], d)] + cs)
    # choose dishes from courses for each diner
    # until all dishes are used up
    def choose(courses, s, ds=[]):
      if len(courses[0]) == 0:
        yield ds
        # find a choice for the next diner, and remaining dishes
        for (d, cs) in dishes(courses, s):
          # require the dishes to be ordered by diner (to remove duplicate solutions)
          if len(ds) > 0 and d < ds[-1]: continue
          yield from choose(cs, s, ds + [d])
    # consider each course
    for (i, c) in enumerate(courses):
      # choose a poisoned dish and a repeated dish
      for (p, r) in permutations(c, 2):
        # how much did A, B, C spend each?
        # (they had all the dishes, except the poisoned one, and the repeated one twice)
        (s, x) = divmod(total - p + r, 3)
        if x > 0: continue
        # construct the courses consumed by A, B, C
        abc = list(courses)
        # in course i remove the poisoned dish and add the repeated dish
        abc[i] = list(courses[i])
        # find choices for A, B, C
        for ds in choose(abc, s):
          printf("poisoned course = {i}, poisoned dish cost = {p}, A/B/C = {ds}", i=i + 1)

    Solution: Dimwit was the only one who had the Aalspastete.

    We can deduce that the other three diners each spent DM 15 and had the following combination of courses:

    Lumpensuppe; Kröte im Loch; Walise Seltenstück.
    Lumpensuppe; Badeburschen; Mausefallekäse.
    Uferschnecken; Blase und Gequiekt; Geflechte Polizistenpudding.

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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: