Enigmatic Code

Programming Enigma Puzzles

Enigma 1484: Classical centuries

From New Scientist #2646, 8th March 2008

I asked some friends to put the letters C, L, X, V or I in each of the boxes of the IV × IV square so that each row, each column (read from top down) and both diagonals (also read downwards) form 10 different valid Roman numerals less than CC, and then add the total of the 10 numbers to give a “score”. Twelve solutions were found, but Pauline noticed that one pair of solutions had scores differing by C, and Robert noticed another pair whose scores differed by C. The scores of Pauline’s pair were both divisible by V.

What were the scores of Robert’s pair? (Give the answer in Roman or Arabic form).

The posting of this puzzle completes my continuous run of Enigma puzzles from when I started doing them every week – with Enigma 1482 – to the most recent puzzle published – Enigma 1725. I’ll keep posting new puzzles as they appear in New Scientist, and also carry on filling in the gaps in my list with old puzzles as long as I can find the text of them. Enjoy!



One response to “Enigma 1484: Classical centuries

  1. Jim Randell 26 November 2012 at 7:50 pm

    In order to get only twelve squares you have to disallow the special case IIII as a permissible representation of 4. The following Python code uses the int2roman() and roman2int from the enigma.py library and runs in 488ms.

    from itertools import product
    from collections import defaultdict
    from enigma import int2roman, roman2int, irange, printf
    # make a list of all 4 digit roman numerals < 200
    # (IIII is a special case and is disallowed)
    # also index them by their first numeral
    romans = set()
    d1 = defaultdict(set)
    for i in irange(1, 199):
      r = int2roman(i)
      if len(r) != 4: continue
    r = defaultdict(list)
    # choose the first column
    for c1 in romans:
      # and then the rows need to start with the digits of c1
      for (r1, r2, r3, r4) in product(*(d1[d] for d in c1)):
        # the first row and the columns
        rs = set((c1, r1, r2, r3, r4))
        # add in the rest of the columns
        rs.update(r1[i] + r2[i] + r3[i] + r4[i] for i in (1, 2, 3))
        # add in the diagonals
        rs.update((r1[0] + r2[1] + r3[2] + r4[3], r1[3] + r2[2] + r3[1] + r4[0]))
        # they all must be different valid roman numerals
        if not(len(rs) == 10 and rs.issubset(romans)): continue
        # compute the score
        score = sum(roman2int(r) for r in rs)
        # and record the square by score
        r[score].append((r1, r2, r3, r4))
        printf("[{score} => {r1} {r2} {r3} {r4}]")
    for (i, ri) in r.items():
      j = i + 100
      if j not in r: continue
      x = ('R' if i % 5 else 'P')
      printf("{x}: {i} => {ri} / {j} => {rj}", rj=r[j])

    Solution: The scores for Robert’s pair are 648 and 748.

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: