Enigmatic Code

Programming Enigma Puzzles

Enigma 538: Rule of the road

From New Scientist #1690, 11th November 1989 [link]

I recently visited Ruralania with its five towns, Arable, Bridle, Cowslip, Dairy, Ewe, joined by one-way roads labelled high or low, as in the map:

Enigma 538

The Ruralanian road system is very simple; if a driver is at one of the five towns then the systems says whether he or she is to leave that town by the high road, by the low road, or to stop in that town.

The system is determined by the fact that it must be possible to make a Grand Tour by starting at a certain town and driving round visiting all the towns and stopping at the final town, while always obeying the single Rule (X):

Take the high road if taking the low road and then obeying Rule (X) again, results in your car next being at A or E. Otherwise, take the low road if taking the high road and then obeying Rule (X) again, results in your car next being at C. Otherwise, stop in the town where you are.

What is the Grand Tour? (List the towns in order).

[enigma538]

One response to “Enigma 538: Rule of the road

  1. Jim Randell 24 February 2020 at 8:03 am

    Any tour defines a map between towns, so we can consider all possible tours, and check that the map conforms to rule X.

    This Python program runs in 81ms.

    Run: [ @repl.it ]

    from enigma import subsets, tuples, join, printf
    
    # the road network: <src> -> (<low road dst>, <high road dst>)
    roads = dict(A='EB', B='CE', C='AD', D='BC', E='DA')
    
    # X is a map from src -> dst
    # dst is result of low road, high road, or stay where you are
    
    # verify a map X conforms to the rules
    def verify(X):
      for (k, v) in X.items():
        # destinations of low and high roads
        (lo, hi) = roads[k]
    
        # (1) if taking the low road and applying X again gives A or E ...
        if X[lo] in 'AE':
          # then take the high road
          if not(v == hi):
            return False
    
        # (2) otherwise, if taking the high road and applying X again gives C ...
        elif X[hi] == 'C':
          # then take the low road
          if not(v == lo):
            return False
    
        # (3) otherwise stay where you are
        else:
          if not(v == k):
            return False
    
      # map is verified
      return True
    
    # consider possible length 5 tours
    for t in subsets(roads.keys(), size=len, select="P"):
      # turn the tour into a map
      X = dict(tuples(t + t[-1:], 2))
      # verify the map
      if not verify(X): continue
      # output solution
      printf("tour = {t}", t=join(t, sep=" "))
    

    Solution: The Grand Tour is: D, C, A, B, E.

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

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

%d bloggers like this: