#!/usr/bin/env python3 # Copyright 2010-2022 Google LLC # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Use CP-SAT to solve a simple cryptarithmetic problem: SEND+MORE=MONEY. """ from absl import app from ortools.sat.python import cp_model def send_more_money(): """Solve the cryptarithmic puzzle SEND+MORE=MONEY.""" model = cp_model.CpModel() # Create variables. # Since s is a leading digit, it can't be 0. s = model.NewIntVar(1, 9, "s") e = model.NewIntVar(0, 9, "e") n = model.NewIntVar(0, 9, "n") d = model.NewIntVar(0, 9, "d") # Since m is a leading digit, it can't be 0. m = model.NewIntVar(1, 9, "m") o = model.NewIntVar(0, 9, "o") r = model.NewIntVar(0, 9, "r") y = model.NewIntVar(0, 9, "y") # Create carry variables. c0 is true if the first column of addends carries # a 1, c2 is true if the second column carries a 1, and so on. c0 = model.NewBoolVar("c0") c1 = model.NewBoolVar("c1") c2 = model.NewBoolVar("c2") c3 = model.NewBoolVar("c3") # Force all letters to take on different values. model.AddAllDifferent(s, e, n, d, m, o, r, y) # Column 0: model.Add(c0 == m) # Column 1: model.Add(c1 + s + m == o + 10 * c0) # Column 2: model.Add(c2 + e + o == n + 10 * c1) # Column 3: model.Add(c3 + n + r == e + 10 * c2) # Column 4: model.Add(d + e == y + 10 * c3) # Solve model. solver = cp_model.CpSolver() if solver.Solve(model) == cp_model.OPTIMAL: print("Optimal solution found!") print("s:", solver.Value(s)) print("e:", solver.Value(e)) print("n:", solver.Value(n)) print("d:", solver.Value(d)) print("m:", solver.Value(m)) print("o:", solver.Value(o)) print("r:", solver.Value(r)) print("y:", solver.Value(y)) def main(_): send_more_money() if __name__ == "__main__": app.run(main)