Enigmatic Code

Programming Enigma Puzzles

Enigma 238: Sort out your draws

From New Scientist #1384, 17th November 1983 [link]

In our local football league the six teams, Algols, Basics, Computers, Digitals, Electronics and Fortrans, each played each other once this season and the end-of-season league table has just been published. The teams finished in alphabetical order with no two teams scoring the same total number of points. We work on the system of 3 points for a win and 1 point for a draw. Just knowing each of the teams’ total points, and the fact that during the season there had been at least twice as many draws as wins, enabled me to work out the result of each match.

Someone beat Basics. Which team (or teams)? And which team(s) beat Fortrans?



One response to “Enigma 238: Sort out your draws

  1. Jim Randell 17 November 2014 at 8:18 am

    This Python program uses the Football() class from the enigma.py library. It runs in 5.5s, so it’s not particularly elegant or particularly fast.

    from collections import defaultdict
    from enigma import Football, printf
    football = Football(games='wdl', points={ 'w': 3, 'd': 1 })
    r = defaultdict(list)
    # matches for A
    for (AB, AC, AD, AE, AF) in football.games(repeat=5):
      A = football.table([AB, AC, AD, AE, AF], [0, 0, 0, 0, 0])
      # remaining matches for B
      for (BC, BD, BE, BF) in football.games(repeat=4):
        B = football.table([AB, BC, BD, BE, BF], [1, 0, 0, 0, 0])
        if not(A.points > B.points): continue
        # remaining matches for C
        for (CD, CE, CF) in football.games(repeat=3):
          C = football.table([AC, BC, CD, CE, CF], [1, 1, 0, 0, 0])
          if not(B.points > C.points): continue
          # remaining matches for D
          for (DE, DF) in football.games(repeat=2):
            D = football.table([AD, BD, CD, DE, DF], [1, 1, 1, 0, 0])
            if not(C.points > D.points): continue
            # remaining match
            for EF in football.games():
              E = football.table([AE, BE, CE, DE, EF], [1, 1, 1, 1, 0])
              F = football.table([AF, BF, CF, DF, EF], [1, 1, 1, 1, 1])
              if not(D.points > E.points > F.points): continue
              # overall there are at least twice as many drawn matches as won matches
              s = (AB, AC, AD, AE, AF, BC, BD, BE, BF, CD, CE, CF, DE, DF, EF)
              n = s.count('d')
              if n < 10: continue
              r[(A.points, B.points, C.points, D.points, E.points, F.points)].append(s)
              printf("AB={AB} AC={AC} AD={AD} AE={AE} AF={AF}")
              printf("BC={BC} BD={BD} BE={BE} BF={BF}")
              printf("CD={CD} CE={CE} CF={CF}")
              printf("DE={DE} DF={DF}")
    # examine the possibilities
    for (k, v) in r.items():
      if len(v) != 1: continue
      (AB, AC, AD, AE, AF, BC, BD, BE, BF, CD, CE, CF, DE, DF, EF) = v[0]
      # find teams that beat B
      bs = list(t for (m, t, x) in zip([AB, BC, BD, BE, BF], 'ACDEF', 'wllll') if m == x)
      if not bs: continue
      # find teams that beat F
      fs = list(t for (m, t, x) in zip([AF, BF, CF, DF, EF], 'ABCDE', 'wwwww') if m == x)
      printf("{k} => {v}")
      printf("B lost to: {bs}", bs=' '.join(bs))
      printf("F lost to: {fs}", fs=' '.join(fs))

    Solution: Basics lost to Algols. Fortrans lost to Algols, Basics and Computers.

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

%d bloggers like this: