Enigmatic Code

Programming Enigma Puzzles

Enigma 185: League reform

From New Scientist #1330, 4th November 1982 [link]

Our local league has four teams, each of whom plays each other once each season. The league table at the end of last season is (with each digit replaced consistently by a letter) partly shown below. This was on the old scheme of two points for a win and one for a draw, and the teams are shown in order of merit (with goal difference deciding the order in the event of ties on points).

Enigma 185

In order to decide whether to switch to the new scheme of three points for a win and one for a draw, we’ve worked out what the table would look like under this new scheme, and that is partly shown too.

Enigma 185 - 2

What were the scores in the six matches? (In the order AvB, AvC, AvD, BvC, BvD, CvD).

[enigma185]

Advertisements

One response to “Enigma 185: League reform

  1. Jim Randell 20 April 2014 at 9:13 am

    This Python program uses the Football() class from the enigma.py library. It runs in 69ms.

    from itertools import permutations
    from enigma import irange, Football, is_pairwise_distinct, printf
    
    # compare points / goal differences
    def is_ordered(pX, pY, dX, dY):
      return pX > pY or (pX == pY and dX > dY)
    
    # single digits
    digits = set(irange(0, 9))
    
    # 2 points / 3 points for a win scoring
    football = Football(games='wdl', points={ 'w': 2, 'd': 1 })
    football3 = Football(games='wdl', points={ 'w': 3, 'd': 1 })
    
    # consider possible match outcomes
    for (AB, AC, AD, BC, BD, CD) in football.games(repeat=6):
      # compute the table
      A = football.table([AB, AC, AD], [0, 0, 0])
      B = football.table([AB, BC, BD], [1, 0, 0])
      C = football.table([AC, BC, CD], [1, 1, 0])
      D = football.table([AD, BD, CD], [1, 1, 1])
      # check the points order
      if not(C.points >= A.points >= B.points >= D.points): continue
      # and the letter assignments
      (P, Q, U) = (C.points, B.points, B.l)
      if A.w != Q: continue
      if not is_pairwise_distinct(P, Q, U): continue
    
      # compute the table under the alternate rules
      A3 = football3.table([AB, AC, AD], [0, 0, 0])
      B3 = football3.table([AB, BC, BD], [1, 0, 0])
      C3 = football3.table([AC, BC, CD], [1, 1, 0])
      D3 = football3.table([AD, BD, CD], [1, 1, 1])
      # check the points order
      if not(A3.points >= C3.points >= B3.points >= D3.points): continue
      # and the letter assignements
      V = C3.points
      if V in (P, Q, U): continue
    
      # possible scorelines for C
      for aC in digits:
        for (sAC, sBC, sCD) in football.scores([AC, BC, CD], [1, 1, 0], Q, aC):
    
          # possible scorelines for B
          for fB in digits:
            for (sAB, sBD) in football.scores([AB, BD], [1, 0], fB, U, [sBC], [0]):
    
              # possible scorelines for A
              for (R, S) in permutations(digits.difference([P, Q, U, V]), 2):
                if not is_ordered(C.points, A.points, Q - aC, R - S): continue
                if not is_ordered(A.points, B.points, R - S, fB - U): continue
                if not is_ordered(A3.points, C3.points, R - S, Q - aC): continue
                if not is_ordered(C3.points, B3.points, Q - aC, fB - U): continue
                for (sAD,) in football.scores([AD], [0], R, S, [sAB, sAC], [0, 0]):
                  # determine goals for/against D
                  (T, aD) = football.goals([sAD, sBD, sCD], [1, 1, 1])
                  if T in (P, Q, U, V, R, S): continue 
                  if not is_ordered(B.points, D.points, fB - U, T - aD): continue
                  if not is_ordered(B3.points, D3.points, fB - U, T - aD): continue
    
                  printf("AB={sAB} AC={sAC} AD={sAD} BC={sBC} BD={sBD} CD={sCD} [P={P} Q={Q} R={R} S={S} T={T} U={U} V={V}]")
    

    Solution: The scores in the matches were: AvB = 1-0; AvC = 0-2; AvD = 8-6; BvC = 0-0; BvD = 0-0; CvD = 0-0.

    However I think it is possible to argue that there could be a second possible solution.

    The scores in the matches could be: AvB = 1-0; AvC = 1-2; AvD = 7-6; BvC = 0-0; BvD = 0-0; CvD = 0-0.

    In this scenario the first table looks like:

      pts w  l  d  f  a  gd
    C: 4  1  0  2  2  1  +1
    A: 4  2  1  0  9  8  +1
    B: 2  0  1  2  0  1  -1
    D: 2  0  1  2  6  7  -1

    Both C and A, and B and D have the same number of points, and the same goal difference, so without further information about how the order of tied teams is decided it is possible that the table would be presented in the order above.

    The second table would look like:

      pts w  l  d  f  a  gd
    A: 6  2  1  0  9  8  +1
    C: 5  1  0  2  2  1  +1
    B: 2  0  1  2  0  1  -1
    D: 2  0  1  2  6  7  -1

    A and C have swapped positions (as required), and V = 5 does not appear as a letter in the first table, so it is consistent with the problem statement.

    This additional solution can be obtained by relaxing the definition of is_ordered() to:

    def is_ordered(pX, pY, dX, dY):
      return pX > pY or (pX == pY and dX >= dY)
    

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: