Enigmatic Code

Programming Enigma Puzzles

Enigma 813: Easy as ABC

From New Scientist #1968, 11th March 1995 [link] [link]

The schedule of matches has been drawn up for the next tournament between Albion, Borough, City, Rangers and United, in which each team will play each of the other teams once. Two matches will take place on each of five successive Saturdays, each of the five teams having one Saturday without a match.

Two of the five teams will be meeting their four opponents in alphabetical order. Given this information you could deduce the complete schedule of matches if I told you either one of the matches scheduled for the first Saturday.

1. Which teams will be meeting their opponents in alphabetical order?

2. Which matches are scheduled for the first Saturday?

[enigma813]

Advertisement

One response to “Enigma 813: Easy as ABC

  1. Jim Randell 6 March 2023 at 9:08 am

    This Python program collects possible schedules where exactly 2 of the teams meet their opponents in alphabetical order, and counts the number of times each first week match occurs in a schedule.

    We then look through the schedules looking for those where both first week matches only correspond to one schedule. And in this case if either of the first week matches was given, we could determine the entire schedule.

    The run time is 82ms. (Internal runtime is 16.0ms).

    Run: [ @replit ]

    from enigma import (defaultdict, subsets, intersect, map2str, join, printf)
    
    # construct the matches
    matches = set(x + y for (x, y) in subsets('ABCRU', size=2))
    
    # construct possible orderings for matches
    def generate(ms, ws=[]):
      if not ms:
        yield ws
      else:
        # choose 2 matches for this week
        for xs in subsets(ms, size=2):
          if intersect(xs): continue
          yield from generate(ms.difference(xs), ws + [sorted(xs)])
    
    # find teams that meet their opponents in alphabetical order
    def ordered(ms):
      d = defaultdict(list)
      for w in ms:
        for (x, y) in w:
          d[x].append(y)
          d[y].append(x)
      for (k, vs) in d.items():
        if vs == sorted(vs):
          yield k
    
    # collect possible schedules
    ss = list()
    # and count the occurrences of the first week matches
    m = defaultdict(int)
    # consider possible matches
    for ms in generate(matches):
      # find teams that meet their opponents in alphabetical order
      ts = list(ordered(ms))
      if len(ts) != 2: continue
      ss.append(ms)
      for g in ms[0]:
        m[g] += 1
    
    # find schedules with unique first week matches
    for ms in ss:
      if not all(m[g] == 1 for g in ms[0]): continue
      # output solution
      printf("{ms}", ms=map2str(enumerate((join(m, sep="+") for m in ms), start=1), arr=": "))
      ts = list(ordered(ms))
      printf("-> (1) {ts}", ts=join(ts, sep=" "))
      printf("-> (2) {w0}", w0=join(ms[0], sep="+"))
      printf()
    

    Solution: (1) City and United meet their opponents in alphabetical order. (2) The first week matches are: Albion vs City; Borough vs Rangers.

    The matches are:

    week 1: A vs C; B vs R
    week 2: A vs U; B vs C
    week 3: B vs U; C vs R
    week 4: A vs R; C vs U
    week 5: A vs B; R vs U

    So the schedules for each team are:

    A: C U _ R B
    B: R C U _ A
    C: A B R U _ [ordered]
    R: B _ C A U
    U: _ A B C R [ordered]

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 )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: