Enigmatic Code

Programming Enigma Puzzles

Enigma 469: Enigmatic dominoes

From New Scientist #1620, 7th July 1988 [link]

I have an ordinary set of 28 dominoes, but I’ve painted over the numbers. I’ve left the blanks alone and painted E’s over the 1’s, N’s over the 2’s, I’s over the 3’s, G’s over the 4’s, M’s over the 5’s and A’s over the 6’s.

My nephew was playing with the dominoes and managed to arrange 18 of them, some “horizontal” and some “vertical”, so that the letters and blanks were in the positions shown.

Enigma 469

I forgot which letters were in the positions marked “?” but I remember that all four “?”s were the same, and no two were on the same domino.

Which letter is “?” and how many of the 18 dominoes were “horizontal”.

[enigma469]

One response to “Enigma 469: Enigmatic dominoes

  1. Jim Randell 8 October 2018 at 8:02 am

    This Python 3 program runs in 130ms.

    Run: [ @repl.it ]

    from enigma import ordered, diff, partition, irange, printf
    
    # assign numbers to the symbols (7 for unknown)
    (E, N, I, G, M, A, _, U, X) = (1, 2, 3, 4, 5, 6, 0, 7, None)
    
    grid = [
      X, X, X, X, X, X, X, X, X, X, X, X, X, X,
      X, A, N, _, _, _, E, N, I, G, M, A, _, X,
      X, _, E, N, I, G, M, A, _, U, U, U, U, X,
      X, G, A, M, E, _, _, E, N, I, G, M, A, X,
      X, X, X, X, X, X, X, X, X, X, X, X, X, X,
    ]
    
    # unallocated squares in the grid
    unallocated = list(i for (i, v) in enumerate(grid) if v != X)
    
    # place dominoes until all squares are allocated
    # ds - dominoes placed
    # ps - positions (i, j, k), k = 1 for horizontal
    def solve(unallocated, ds=[], ps=[]):
      if not unallocated:
        yield (ds, ps)
      else:
        i = unallocated[0]
        s = list()
        if i + 1 in unallocated:
          # attempt to place a horizontal domino at (i, i+1)
          s.append((i, i + 1, 1))
        if i + 14 in unallocated:
          # attempt to place a vertical domino at (i, i+14)
          s.append((i, i + 14, 0))
        for (i, j, k) in s:
          # determine the domino at (i, j)
          d = ordered(grid[i], grid[j])
          # dominoes can't be repeated
          if d in ds: continue
          # solve for the remaining dominoes
          yield from solve(diff(unallocated, (i, j)), ds + [d], ps + [(i, j, k)])
    
    # replace u with v in tuple t
    def replace(t, u, v):
      return tuple(v if x == u else x for x in t)
    
    # find "unknown" value from a set of dominoes
    def unknown(ds):
      # separate the dominoes in to knowns, unknowns
      (unknowns, knowns) = partition((lambda d: U in d), ds)
      # consider possible unknown values
      for n in irange(0, 6):
        # replacement dominoes
        rs = set(ordered(*(replace(d, U, n))) for d in unknowns)
        if len(rs) != len(unknowns): continue
        if rs.intersection(knowns): continue
        yield (n, rs.union(knowns))
    
    # solve the grid
    for (ds, ps) in solve(unallocated):
      # can't have 2 unknowns on the same domino
      if (U, U) in ds: continue
      # allocate the unknown number
      for (n, rs) in unknown(ds):
        # output solution
        h = sum(k for (i, j, k) in ps)
        printf("? = {n}, horizontal = {h}", n="_ENIGMA"[n])
        # output dominoes and positions
        for (d, (i, j, k)) in zip(ds, ps):
          (a, b) = ordered(*(replace(d, U, n)))
          printf("  {a}-{b} @ {i},{j} {k}", k='VH'[k])
        printf(
    

    Solution: The squares marked with “?” should be “I”. There are 6 horizontal dominoes.

    There is only one layout that satisfies all the conditions:

    Without the condition that there can’t be two “unknowns” on the same domino there is a further solution with 8 horizontal dominoes.

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: