Enigmatic Code

Programming Enigma Puzzles

Enigma 1613: Odd one out

From New Scientist #2778, 18th September 2010 [link]

There are five teams in our local football league and each plays each other once in the season, earning 3 points for a win and 1 for a draw. Here is the league table from the end of last season, but only part of it is shown. And digits have consistently been replaced by letters, with different letters used for different digits. The teams are in decreasing order of points, with no two tied. List the results in those games which were not draws, in the form “X beat Y”.

Enigma 1695 is also called “Odd one out”.

[enigma1613]

Advertisements

One response to “Enigma 1613: Odd one out

  1. jimrandell 29 December 2011 at 1:32 pm

    The following Python program runs in 450ms.

    # each match can have three outcomes
    
    # consider the matches:
    
    #  0  1  2  3  4  5  6  7  8  9
    # AB AC AD AE BC BD BE CD CE DE
    
    # for each match XY, 0 = Y wins, 1 = draw, 2 = X wins
    
    from itertools import product
    from enigma import is_pairwise_distinct, printf
    
    def points(ms):
      (w, d, l, p) = (0, 0, 0, 0)
      for m in ms:
        if m == 2:
          # win
          w += 1
          p += 3
        elif m == 1:
          # draw
          d += 1
          p += 1
        elif m == 0:
          # lose
          l += 1
      return { 'w': w, 'd': d, 'l': l, 'p': p }
    
    def main():
      for m in product((0, 1, 2), repeat=10):
        A = points((m[0], m[1], m[2], m[3]))
        B = points((2 - m[0], m[4], m[5], m[6]))
        C = points((2 - m[1], 2 - m[4], m[7], m[8]))
        D = points((2 - m[2], 2 - m[5], 2 - m[7], m[9]))
        E = points((2 - m[3], 2 - m[6], 2 - m[8], 2 - m[9]))
    
        # points are in order (and are all different)
        if not(A['p'] > B['p'] > C['p'] > D['p'] > E['p']): continue
    
        o = B['d']
        if not(C['l'] == o): continue
        d = B['l']
        t = D['p']
    
        if not is_pairwise_distinct(o, d, t): continue
    
        if not (d >= B['w']): continue
    
        printf("A: {w:>2} {d:>2} {l:>2} {f:>2} {a:>2} {p:>2}", w=A['w'], d=A['d'], l=A['l'], f='?', a='?', p=A['p'])
        printf("B: {w:>2} {d:>2} {l:>2} {f:>2} {a:>2} {p:>2}", w=B['w'], d=B['d'], l=B['l'], f=d,   a='?', p=B['p'])
        printf("C: {w:>2} {d:>2} {l:>2} {f:>2} {a:>2} {p:>2}", w=C['w'], d=C['d'], l=C['l'], f='n', a='e', p=C['p'])
        printf("D: {w:>2} {d:>2} {l:>2} {f:>2} {a:>2} {p:>2}", w=D['w'], d=D['d'], l=D['l'], f=o,   a='u', p=D['p'])
        printf("E: {w:>2} {d:>2} {l:>2} {f:>2} {a:>2} {p:>2}", w=E['w'], d=E['d'], l=E['l'], f='?', a='?', p=E['p'])
        printf('')
    
        M = ( 'AB', 'AC', 'AD', 'AE', 'BC', 'BD', 'BE', 'CD', 'CE', 'DE' )
        for (i, mi) in enumerate(m):
          (x, y) = M[i]
          if mi == 2: printf("{x} beat {y}")
          elif mi == 1: printf("{x} draw {y}")
          elif mi == 0: printf("{y} beat {x}")
    
    main()
    

    Solution: The non-draw games are: Ailing beat Beeling, Ailing beat Ceiling, Ailing beat Deeling, Ailing beat Ealing, Beeling beat Ceiling and Ceiling beat Ealing.

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: