Enigmatic Code

Programming Enigma Puzzles

Enigma 322: More and better goals

From New Scientist #1470, 22nd August 1985 [link]

The new method of rewarding goals scored in football matches is a great success. And some people say that the goals have increased not only in quantity but also in quality.

In this method 10 points are awarded for a win, 5 points for a draw and 1 point for each goal scored.

In a recent competition between 4 teams (ABC and D), A got 5 points, B got 35 points, C got 20 points, and D got 4 points, after some — or perhaps all — of the matches were played.

Not more than 10 goals were scored in any match and that number was only scored in one. Each side scored at least 1 goal in every game.

What was the score in each match?

It’s now 4 years since I started the Enigmatic Code site, and we have 916 Enigma puzzles on the site, which is just over half the total number of Enigma puzzles published in New Scientist between 1979 and 2013. There is a complete archive from the very first Enigma puzzle in January 1979 up to August 1985, and from June 2002 to the final Enigma puzzle in December 2013.

I aim to keep adding puzzles as long as I am able to source them. I currently need to get puzzles from #545 (January 1990) to #1154 (October 2001), along with #1166 (22nd? December 2001), #1176 (2nd March 2002), #1181 (6th April 2002) and #1186 (11th May 2002), (altogether around 600 puzzles), so I shall have to try and get to a reference library to get access to back issues of the magazine.

Thank you to everyone who has joined in by sharing their own solutions and insights.


3 responses to “Enigma 322: More and better goals

  1. Jim Randell 4 December 2015 at 9:04 am

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

    from enigma import Football, irange, printf
    # scoring regime (points for goals will need to be added)
    football = Football(points={ 'w': 10, 'd': 5 })
    # in each game played each side scores at least 1 goal
    # so a winning team must score at least 2 goals
    # also not more than 10 goals are scored in any individual match,
    # so possible winning scores are:
    # 9-1
    # 8-1, 8-2
    # 7-1, 7-2, 7-3
    # 6-1, 6-2, 6-3, 6-4
    # 5-1, 5-2, 5-3, 5-4
    # 4-1, 4-2, 4-3
    # 3-1, 3-2
    # 2-1
    # possible drawn scores are:
    # 1-1, 2-2, 3-3, 4-4, 5-5
    # check for valid scores
    def check(*scores):
      for s in scores:
        if s is None: continue
        (a, b) = s
        if a < 1 or b < 1 or a + b > 10: return False
      return True
    # goals scored based on actual points and a table entry
    def goals_for(pts, X):
      f = pts - X.points
      if f < X.played + X.w: return None
      return f
    # possible goals conceded based on a table entry
    def goals_against(X):
      return irange(X.played + X.l, 9 * X.l + 5 * X.d + 4 * X.w)
    # consider matches for D (4 points)
    for (AD, BD, CD) in football.games(repeat=3):
      D = football.table([AD, BD, CD], [1, 1, 1])
      fD = goals_for(4, D)
      if fD is None: continue
      # consider matches for A (5 points)
      for (AB, AC) in football.games(repeat=2):
        A = football.table([AB, AC, AD], [0, 0, 0])
        fA = goals_for(5, A)
        if fA is None: continue
        # consider matches for C (20 points)
        for BC in football.games():
          C = football.table([AC, BC, CD], [1, 1, 0])
          fC = goals_for(20, C)
          if fC is None: continue
          B = football.table([AB, BC, BD], [1, 0, 0])
          fB = goals_for(35, B)
          if fB is None: continue
          # now assign the scores for D's games
          for aD in goals_against(D):
            for (sAD, sBD, sCD) in football.scores([AD, BD, CD], [1, 1, 1], fD, aD):
              if not check(sAD, sBD, sCD): continue
              # and A's games
              for aA in goals_against(A):
                for (sAB, sAC) in football.scores([AB, AC], [0, 0], fA, aA, [sAD], [0]):
                  if not check(sAB, sAC): continue
                  # and the remaining match (from C's point of view)
                  for aC in goals_against(C):
                    for (sBC,) in football.scores([BC], [1], fC, aC, [sAC, sCD], [1, 0]):
                      if not check(sBC): continue
                      # check B's "goals for" is as previously determined
                      (f, aB) = football.goals([sAB, sBC, sBD], [1, 0, 0])
                      if f != fB: continue
                      # count the number of matches with a total goal count of 10
                      t = sum(1 for s in (sAB, sAC, sAD, sBC, sBD, sCD) if s is not None and sum(s) == 10)
                      if t != 1: continue
                      printf("AB={AB}:{sAB} AC={AC}:{sAC} AD={AD}:{sAD} BC={BC}:{sBC} BD={BD}:{sBD} CD={CD}:{sCD}")
                      printf("A={A} fA={fA} aA={aA}")
                      printf("B={B} fB={fB} aB={aB}")
                      printf("C={C} fC={fC} aC={aC}")
                      printf("D={D} fD={fD} aD={aD}")

    Solution: The scores in the played matches are: A v B = 2-3; A v C = 3-4; B v C = 1-1; B v D = 6-4.

    The remaining matches (A v D, C v D) are not yet played.

  2. Jim Olson 5 December 2015 at 4:22 pm

    Thank you for all the work,time and effort you put into this site.
    It is much appreciated!

    • Julian Gray 7 December 2015 at 3:28 pm

      Yes I second that. “Enigma” is an immensely fulfilling part of my (fortunately long and happy) retirement – I don’t do programming, except surprisingly frequently and usefully with Excel, but simply tackling the puzzles is a lot of fun. And it keeps me out of the kitchen.

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: