Enigmatic Code

Programming Enigma Puzzles

Tantalizer 3: Café de Gaulle

From New Scientist #552, 6th July 1967 [link]

My friend Jones has food poisoning, which serves him right. Last night he thought he would impress two girls by taking them to dinner at the newly opened Café de Gaulle. Since the girls have survived the ordeal, we may assume that the trouble lay in a dish which Jones ate and they did not.

The menu was this:

Potage Tiede … 1s
Haricots sur Toast … 2s
Coctaile de Crevettes … 3s

Bulle et Couic … 4s
Crapeau dans le Trou … 5s
Trotteurs de Cochon … 6s

Fromage Souriciere … 2s
Morceau Singulier Gallois … 3s
Becasse Ecossaise … 4s

Jones tells me that each of them ate one item from each course and that, not counting tips etc., he paid eight shillings for himself, nine shillings for Polly and 10s for Gladys. No dish eaten by Polly was also eaten by Gladys.

He was in fact able to recall what the girls had eaten and so even though he had forgotten what he ate himself, we could deduce what had poisoned him. The offending dish can, however, be deduced merely from the information given so far plus the information that someone had Becasse Ecossaise.

Which is it?

In the book Tantalizers (1970) a reworded version of this puzzle appears under the title: “Café des Gourmets”.

[tantalizer3]

One response to “Tantalizer 3: Café de Gaulle

  1. Jim Randell 22 March 2023 at 8:55 am

    See also: Enigma 236.

    This Python program constructs possible meals (one dish from each course) by price, and then allocates appropriate meals to each of the three participants, such that P and G has no dish in common, and there is a single candidate poisonous dish that is eaten by J alone.

    We then look for situations where if we knew which dishes were eaten by P and G (although not necessarily who ate what), we could deduce the poisoned dish. From these candidates we select those that include the dish BE.

    This Python program runs in 64ms. (Internal runtime is 470µs).

    Run: [ @replit ]

    from enigma import (group, cproduct, union, diff, singleton, ordered, filter_unique, item, joinf, printf)
    
    # courses and prices
    courses = [ dict(PT=1, HT=2, CC=3), dict(BC=4, CT=5, TC=6), dict(FS=2, MG=3, BE=4) ]
    
    # group a full meal by its price
    price = lambda ks: sum(d[k] for (d, k) in zip(courses, ks))
    g = group(cproduct(d.keys() for d in courses), by=price)
    
    # generate candidate dishes, and potential poisonous dishes
    # return (P+G, poisoned, J, P, G)
    def generate():
      # choose the meals
      for (J, P, G) in cproduct([g[8], g[9], g[10]]):
        # P and G had no dishes in common
        PG = union([P, G])
        if len(PG) != 6: continue
        # can we identify the poisonous dish?
        # (i.e. a dish eaten by J alone)
        xxx = singleton(diff(J, PG))
        if xxx:
          yield (ordered(*PG), xxx, J, P, G)
    
    # if we knew what P and G had eaten (item 0) we could deduce the poisoned dish (item 1)
    ss = filter_unique(generate(), item(0), item(1)).unique
    
    # now we can identify the poisoned dish knowing that someone had BE
    fmt = joinf(sep=" ", enc="()")
    for (_, xxx, J, P, G) in ss:
      if 'BE' in union([J, P, G]):
        printf("{xxx} -> J={J} P={P} G={G}", J=fmt(J), P=fmt(P), G=fmt(G))
    

    Solution: The poison dish was: Fromage Souriciere.

    We have the following possible orders:

    Jones = PT, CT, FS / HT, BC, FS [8s]
    → Polly = PT, BC, BE [9s]; Gladys = HT, CT, MG [10s]
    → Polly = PT, CT, MG [9s]; Gladys = HT, BC, BE [10s]
    → Polly = HT, BC, MG [9s]; Gladys = PT, CT, BE [10s]

    The dishes are (thanks to Hugh Casement for the translations):

    PT = tepid soup
    HT = beans on toast
    CC = prawn cocktail

    BC = bubble and squeak
    CT = toad in the hole
    TC = pig trotters

    FS = mousetrap cheese
    MG = Welsh rarebit (“rare bit” = “singular piece”)
    BE = Scotch woodcock

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 )

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: