Enigmatic Code

Programming Enigma Puzzles

Enigma 1447: Bonus points

From New Scientist #2608, 16th June 2007

Albion, Borough, City, Rangers and United have played another tournament in which each team played each of the others once, two matches being played on each of five successive Saturdays, each team having one Saturday without a match. Points were awarded according to a formula now widely used in Rugby: 4 points for a win, 2 points to each team for a draw, and in any match either team or both teams might also gain 1 bonus point.

After the first Saturday’s match Albion led the tournament, followed in order by Borough, City, Rangers and United, 1 point separating each pair of successive teams. After the second Saturday’s matches 1 point still separated each pair of successive teams, but no team was in the same position as after the first Saturday’s matches.

If I identified my team and told you what position it was in after the second Saturday’s matches you could deduce with certainty which matches had been played on that day and how many points each team had gained in them.

Which matches were played on the second Saturday, and how many points did each team gain in them?

[enigma1447]

Advertisements

One response to “Enigma 1447: Bonus points

  1. Jim Randell 25 March 2013 at 10:17 am

    This Python program examines all possible outcomes for the second Saturday. It runs in 47ms.

    It uses the partitions() function added to the enigma.py library for Enigma 1449 (and Enigma 70).

    from itertools import combinations, product
    from collections import defaultdict
    from enigma import diff, partitions, printf
    
    # after the first Saturday the order is:
    # A > B > C > R > U
    # but one team hasn't played yet, so has 0 points, so:
    # A = 4 > B = 3 > D = 2 > R = 1 > U = 0
    # hence the matches were:
    # A vs R: A won (4 points), R bonus (1 point)
    # B vs C: draw, B bonus (3 points), C (2 points)
    
    # teams
    teams = tuple('ABCRU')
    
    # possible scores for a match, including bonus points
    match = (
      (4, 0), (5, 0), (4, 1), (5, 1),
      (2, 2), (3, 2), (2, 3), (3, 3),
      (0, 4), (1, 4), (0, 5), (1, 5),
    )
    
    # matches already played
    played = set((('A', 'R'), ('B', 'C')))
    
    # record results by team and position
    r = defaultdict(list)
    # choose the team that doesn't play (from A, B, C, R)
    for n in diff(teams, 'U'):
      # pair up the remaining teams
      for (m1, m2) in partitions(diff(teams, n), 2):
        # don't repeat any matches
        if m1 in played or m2 in played: continue
        for (s1, s2) in product(match, repeat=2):
          # scores after the first round
          s = { 'A': 4, 'B': 3, 'C': 2, 'R': 1, 'U': 0 }
          # add in the second round scores
          s[m1[0]] += s1[0]
          s[m1[1]] += s1[1]
          s[m2[0]] += s2[0]
          s[m2[1]] += s2[1]
          # what are the points?
          pts = s.values()
          # pts values should be distinct
          if len(set(pts)) != 5: continue
          # the teams should be 1 point apart
          if max(pts) - min(pts) != 4: continue
          # what order are the teams in?
          t = sorted(s.keys(), key=lambda x: s[x], reverse=True)
          if any(t[i] == x for (i, x) in enumerate(teams)): continue
          # record results by team and position
          for p in enumerate(t):
            r[p].append((m1, s1, m2, s2))
      
    # look for results that give a unique solution
    for (k, v) in r.items():
      if len(v) != 1: continue
      (m1, s1, m2, s2) = v[0]
      printf("{k[1]} #{r} => {m1[0]} vs {m1[1]}: {s1[0]}pts, {s1[1]}pts / {m2[0]} vs {m2[1]}: {s2[0]}pts, {s2[1]}pts", r=k[0] + 1)
    

    Solution: The matches on the second Saturday are as follows – Borough plays United, each side gains 3 points (so the match is drawn and each side is awarded a bonus point); City plays Rangers, Rangers gains 4 points, City gains no points (so Rangers won the match and no bonus points are awarded).

    Although the participants and points are uniquely determined, the setters team and position on the second Saturday are not. There are three possible solutions – the setter supports United and they are placed 4th; the setter supports Rangers and they are placed 2nd; the setter supports Borough and they are placed 1st.

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: