With the holiday season approaching, Charles Trigg proposed this festive cryptarithm in The American Mathemematical Monthly1, edition December 1956.

christmas puzzle
This puzzle consists of a sentence whose words contain ten different uppercase letters, and are separated by a single space. If each letter is a unique representation of a digit, and each word is a perfect square, what are the four numbers?

This sentence contains ten different letters. If each letter is a unique representation of a digit, and each word is a perfect square2, what are the four numbers?

The puzzle turned out to have two different solutions. The table below shows how the letters have to be replaced by digits to get these two solutions.

letter solution 1 solution 2
M 2 3
E 7 4
R 5 2
Y 6 5
X 3 7
A 4 9
S 9 6
T 8 8
O 1 1
L 0 0

The four perfect squares of the first solution are:

solution
One of two possible solutions of the puzzle.

The four perfect squares of the second solution are 34225 7396 81 900. If we would fine-tune the puzzle to MERRY XMAS TO YA ALL, then YA is replaced by 59 in the second solution, which is not a perfect square. However, the first solution remains correct, as it results in the following perfect squares: 27556 3249 81 64 400.

Assignment

Solve a puzzle where the words of a given sentence (str) contain ten different uppercase letters. The words of the sentence are separated by a single space.

A solution of the puzzle is a one-to-one correspondence (a bijection3) between the ten uppercase letters in the sentence and the ten digits. A solution is only valid in case each word of the sentence is a perfect square when all letters of the sentence are replaced by their corresponding digit. We use two different representations for a solution.

The dictionary representation of a solution is a dictionary (dict) that maps ten different uppercase letters onto the ten digits, with the digits represented as integers.

The string representation of a solution consists of two strings (str). The first string contains ten different uppercase letters. The second string contains the ten digits, with each uppercase letter of the first string corresponding to the digit at the same position in the second string. The second string does not have to be mentioned explicitly if the ten letters in the first string are mapped onto the digits 0, 1, 2, …, 9.

Your task:

The functions solution and iscorrect must raise an AssertionError with the message invalid solution in case the first argument of the given solution is not a string containing ten different uppercase letters or in case the second argument of the given solution is not a string that contains the ten different digits.

The functions replace and isCorrect must raise an AssertionError with the message invalid puzzle in case the words of the given sentence are not composed of the letters in the given solution or are not separated from each other by a single space.

Example

>>> solution('LOMXARYETS')
{'L': 0, 'O': 1, 'M': 2, 'X': 3, 'A': 4, 'R': 5, 'Y': 6, 'E': 7, 'T': 8, 'S': 9}
>>> solution('AELMORSTXY', '4702159836')
{'L': 0, 'O': 1, 'M': 2, 'X': 3, 'A': 4, 'R': 5, 'Y': 6, 'E': 7, 'T': 8, 'S': 9}
>>> solution('MERYXASTOL', '2765349810')
{'L': 0, 'O': 1, 'M': 2, 'X': 3, 'A': 4, 'Y': 5, 'R': 6, 'E': 7, 'T': 8, 'S': 9}
>>> solution('BANANARAMA')
Traceback (most recent call last):
AssertionError: invalid solution

>>> l2c = solution('LOMXARYETS')
>>> replace('MERRY XMAS TO ALL', l2c)
'27556 3249 81 400'
>>> replace('MERRY XMAS TO YA ALL', l2c)
'27556 3249 81 64 400'

>>> l2c = solution('LORMEYSXTA')
>>> replace('MERRY XMAS TO ALL', l2c)
'34225 7396 81 900'
>>> replace('HAPPY NEWYEAR', l2c)
Traceback (most recent call last):
AssertionError: invalid puzzle

>>> issquare(27556)
True
>>> issquare(34225)
True
>>> issquare(12345)
False

>>> iscorrect('MERRY XMAS TO ALL', 'LOMXARYETS')
True
>>> iscorrect('MERRY XMAS TO ALL', 'LORMEYSXTA')
True
>>> iscorrect('MERRY XMAS TO YA ALL', 'AELMORSTXY', '4702159836')
True
>>> iscorrect('MERRY XMAS TO YA ALL', 'MERYXASTOL', '2765349810')
False
>>> iscorrect('MERRY XMAS TO ALL', 'BANANARAMA')
Traceback (most recent call last):
AssertionError: invalid solution
>>> iscorrect('HAPPY NEWYEAR', 'LOMXARYETS')
Traceback (most recent call last):
AssertionError: invalid puzzle

Epilogue

L.A. Ringenberg of the Eastern Illinois State College was the first to find the two solutions of the initial puzzle. He described as follows how he obtained these two solutions.

A table of perfect squares shows that ALL must be 100, 144, 400 or 900. If it's either of the first two, then XMAS has to be 2916 or 9216, and TO can't be a perfect square. If ALL is 400, then XMAS has to be 1849, 3249, 6241 or 8649. Taking these four possibilities in turn:

  1. if ALL = 400 and XMAS = 1849, then M = 8, MERRY = 81225, and E and X now both represent 1, so that can't be right

  2. if ALL = 400 and XMAS = 3249, then M = 2, MERRY = 27556, and TO = 81, which produces a valid solution: 27556 3249 81 400

  3. if ALL = 400 and XMAS = 6241, then TO isn't a perfect square

  4. if ALL = 400 and XMAS = 8649, then M = 6 and L = 0 and there's no solution for MERRY

Finally, going back to the possibility that ALL = 900, in this case XMAS has to be 1296 or 7396:

  1. if ALL = 900 and XMAS = 1296, then TO isn't a perfect square

  2. if ALL = 900 and XMAS = 7396, then M = 3, MERRY = 34225, and TO = 81, giving a second solution: 34225 7396 81 900

Resources