In [ ]:
%%HTML
<style>
.container { width:100% !important; }
</style>
In this notebook we formulate the crypto-arithmetic puzzle shown in the picture below as a constraint satisfaction problem.
The idea is that the letters
"$\texttt{S}$", "$\texttt{E}$", "$\texttt{N}$", "$\texttt{D}$", "$\texttt{M}$", "$\texttt{O}$", "$\texttt{R}$", "$\texttt{Y}$" occurring in this puzzle
are interpreted as variables ranging over the set of decimal digits, i.e. these variables can take values in
the set $\{0,1,2,3,4,5,6,7,8,9\}$. Then, the string "$\texttt{SEND}$" is interpreted as a decimal number,
i.e. it is interpreted as the number
$$\texttt{S} \cdot 10^3 + \texttt{E} \cdot 10^2 + \texttt{N} \cdot 10^1 + \texttt{D} \cdot 10^0.$$
The strings "$\texttt{MORE}$ and "$\texttt{MONEY}$" are interpreted similarly. To make the problem
interesting, the assumption is that different variables have different values.
Furthermore, the digits at the beginning of a number should be different from $0$. Then, we have to find values such that the formula
$$ (\texttt{S} \cdot 10^3 + \texttt{E} \cdot 10^2 + \texttt{N} \cdot 10 + \texttt{D})
For a set $V$ of variables, the function $\texttt{allDifferent}(V)$ generates a set of formulas that express that all the variables of $V$ are different.
In [ ]:
def allDifferent(Variables):
return { f'{x} != {y}' for x in Variables
for y in Variables
if x < y
}
The function crypto_csp
computes a constraint satisfaction problem that encodes the crypto-arithmetic puzzle shown above.
In [ ]:
def crypto_csp():
Digits = { 'S', 'E', 'N', 'D', 'M', 'O', 'R', 'Y' }
Variables = Digits | { 'C1', 'C2', 'C3' }
Values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
Constraints = allDifferent(Digits)
Constraints |= { '(D + E) % 10 == Y', '(D + E) // 10 == C1',
'(N + R + C1) % 10 == E', '(N + R + C1) // 10 == C2',
'(E + O + C2) % 10 == N', '(E + O + C2) // 10 == C3',
'(S + M + C3) % 10 == O', '(S + M + C3) // 10 == M'
}
Constraints |= { 'S != 0', 'M != 0' }
# Constraints |= { 'C1 < 2', 'C2 < 2', 'C3 < 2' }
return Variables, Values, Constraints
In [ ]:
puzzle = crypto_csp()
puzzle
In [ ]:
def show_solution(A):
if A == None:
print("no solution found")
return
for v in { "S", "E", "N", "D", "M", "O", "R", "Y" }:
print(f"{v} = {A[v]}")
print("\nThe solution of\n")
print(" S E N D")
print(" + M O R E")
print(" ---------")
print(" M O N E Y")
print("\nis as follows\n")
print(f" {A['S']} {A['E']} {A['N']} {A['D']}")
print(f" + {A['M']} {A['O']} {A['R']} {A['E']}")
print(f" ==========")
print(f" {A['M']} {A['O']} {A['N']} {A['E']} {A['Y']}")
In [ ]: