Enigmatic Code

Programming Enigma Puzzles

Puzzle 1: Factory exam

From New Scientist #1052, 19th May 1977 [link]

There has been a lot of excitement recently about an examination which four of our employees — Alf, Bert, Charlie and Duggie — have been having in French and mathematics.

Now that we are in the Common Market it is important that we should move with the times and learn some French. And in a modern factory such as ours we must know about all the latest mathematical ideas.

It is interesting that Bert’s French place was a much above his mathematics place as Charlie’s mathematics place was below his French place. Alf’s place was even at both subjects, and Duggie’s place was odd at both. Bert was not top at either subject, and no one had the same place at both. There were no ties.

Find the order in both subjects.

This was the first in a series of puzzles called Puzzle set by Eric Emmet in New Scientist between May 1977 and February 1979 (when it was replaced by Enigma). As with his Enigma puzzles these seem to consist mostly of substituted sums, substituted divisions and football table problems.

[puzzle1]

Advertisements

2 responses to “Puzzle 1: Factory exam

  1. Jim Randell 7 October 2015 at 8:17 am

    This Python program runs in 33ms.

    from itertools import permutations
    from enigma import printf
    
    # indices for A, B, C, D
    (A, B, C, D) = (0, 1, 2, 3)
    
    # choose placements for Maths
    for M in permutations((1, 2, 3, 4)):
    
      # "A's place was even in both subjects"
      if M[A] % 2 != 0: continue
    
      # "D's place was odd in both subjects"
      if M[D] % 2 != 1: continue
    
      # "B was not top at either subject"
      if M[B] == 1: continue
    
      # now choose the placements for French
      for F in permutations((1, 2, 3, 4)):
    
        # "A's place was even in both subjects"
        if F[A] % 2 != 0: continue
    
        # "D's place was odd in both subjects"
        if F[D] % 2 != 1: continue
    
        # "B was not top at either subject"
        if F[B] == 1: continue
    
        # "no one had the same place in both subjects"
        if any(m == f for (m, f) in zip(M, F)): continue
    
        # B's placement in French was as much above his placement in Maths
        # as C's placement in Maths was _below_ his placement in French
        if M[B] - F[B] != M[C] - F[C]: continue
    
        # output the positions
        for (n, i) in zip('ABCD', (A, B, C, D)):
          printf("{n}: Maths = {m}, French = {f}", m=M[i], f=F[i])
        printf()
    

    Solution: In Mathematics: 1st = Duggie, 2nd = Alf, 3rd = Charlie, 4th = Bert. In French: 1st = Charlie, 2nd = Bert, 3rd = Duggie, 4th = Alf.

    This is the published solution, and is the only solution if we assume that Bert’s placement in French was better than his placement in Maths. If we allow it to be worse (so the amount his placement in French was above his placement in Mathematics would be negative) then there is a further solution:

    In Mathematics: 1st = Charlie, 2nd = Bert, 3rd = Duggie, 4th = Alf. In French: 1st = Duggie, 2nd = Alf, 3rd = Charlie, 4th = Bert.

    This solution has the same positions as the published solution, but with the subjects swapped over.

  2. geoffrounce 5 July 2016 at 4:49 pm

    A piece of history here, mentioning the Common Market!

    By setting the Configuration in MiniZinc to multiple solutions, I managed to get the two solutions mentioned by Jim, the first solution being the published solution

    % An early pre Enigma puzzle solution in MiniZinc
    include "globals.mzn"; 
    
    int: n = 4;    % total exam entrants
    int: Alf = 1;  
    int: Bert = 2;  
    int: Charlie = 3; 
    int: Duggie = 4;
    
    % Decision variables for exam results
    array[1..n] of var 1..n: French;
    array[1..n] of var 1..n: Maths;
    
    constraint all_different(French) /\ all_different(Maths);
    
    % Bert’s French place was as much above his Mathematics place 
    % as Charlie’s Mathematics place was below his French place.
    constraint French[Bert] - Maths[Bert] =  French[Charlie] - Maths[Charlie];
    
    % Alf's place was even in both subjects
    constraint French[2] = Alf \/ French [4] == Alf;
    constraint Maths[2] = Alf \/ Maths[4] == Alf;
    
    % Duggie’s place was odd in both subjects
    constraint Maths[1] == Duggie \/ Maths[3] == Duggie;
    constraint French[1] == Duggie \/ French[3] == Duggie;
    
    % Bert was not top at either subject
    constraint Maths[1] != Bert /\ French[1] != Bert;
    
    % No one had the same place in both exams
    constraint forall(i in 1..n) 
      (
       French[i] != Maths[i]
      );
    
    solve satisfy;
    
    output ["French: " ++ show(French) ++ "\n" ++
            "Maths:  " ++ show(Maths) ++ "\n"];
    
    % if MiniZinc configuration is set for multiple solutions...
    % --------Published Solution ( ie 1st, 2nd, 3rd, 4th)
    % French: [3, 2, 4, 1]  ie  Charlie, Bert, Duggie, Alf
    % Maths:  [4, 1, 3, 2]  ie  Duggie, Alf, Charlie, Bert
    %
    % ------ 2nd solution ------
    % French: [4, 1, 3, 2]  ie Duggie, Alf, Charlie, Bert
    % Maths:  [3, 2, 4, 1]  ie Charlie, Bert, Duggie, Alf
    % ----------
    % Finished in 78msec
    %
    
    

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: