00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "base/commandlineflags.h"
00023 #include "base/commandlineflags.h"
00024 #include "base/logging.h"
00025 #include "base/scoped_ptr.h"
00026 #include "constraint_solver/constraint_solver.h"
00027
00028 namespace operations_research {
00029
00030 void Cryptoarithmetics() {
00031 Solver solver("cryptarithm");
00032
00033
00034 IntVar* s = solver.MakeIntVar(1, 9, "s");
00035 IntVar* m = solver.MakeIntVar(1, 9, "m");
00036 IntVar* o = solver.MakeIntVar(0, 9, "o");
00037 IntVar* e = solver.MakeIntVar(0, 9, "e");
00038 IntVar* n = solver.MakeIntVar(0, 9, "n");
00039 IntVar* d = solver.MakeIntVar(0, 9, "d");
00040 IntVar* r = solver.MakeIntVar(0, 9, "r");
00041 IntVar* y = solver.MakeIntVar(0, 9, "y");
00042
00043 std::vector<IntVar*> letters;
00044 letters.push_back(s);
00045 letters.push_back(m);
00046 letters.push_back(o);
00047 letters.push_back(e);
00048 letters.push_back(n);
00049 letters.push_back(d);
00050 letters.push_back(r);
00051 letters.push_back(y);
00052
00053 solver.AddConstraint(solver.MakeAllDifferent(letters));
00054
00055
00056 IntVar* c1 = solver.MakeIntVar(0, 1, "c1");
00057 IntVar* c2 = solver.MakeIntVar(0, 1, "c2");
00058 IntVar* c3 = solver.MakeIntVar(0, 1, "c3");
00059
00060
00061 IntVar* v1 = solver.MakeSum(e, d)->Var();
00062 IntVar* v2 = solver.MakeSum(y, solver.MakeProd(c1, 10))->Var();
00063 solver.AddConstraint(solver.MakeEquality(v1, v2));
00064
00065 v1 = solver.MakeSum(solver.MakeSum(c1, n), r)->Var();
00066 v2 = solver.MakeSum(e, solver.MakeProd(c2, 10))->Var();
00067 solver.AddConstraint(solver.MakeEquality(v1, v2));
00068
00069 v1 = solver.MakeSum(solver.MakeSum(c2, e), o)->Var();
00070 v2 = solver.MakeSum(n, solver.MakeProd(c3, 10))->Var();
00071 solver.AddConstraint(solver.MakeEquality(v1, v2));
00072
00073 v1 = solver.MakeSum(solver.MakeSum(c3, s), m)->Var();
00074 v2 = solver.MakeSum(o, solver.MakeProd(m, 10))->Var();
00075 solver.AddConstraint(solver.MakeEquality(v1, v2));
00076
00077 DecisionBuilder* const db = solver.MakePhase(letters,
00078 Solver::CHOOSE_FIRST_UNBOUND,
00079 Solver::ASSIGN_MIN_VALUE);
00080 solver.NewSearch(db);
00081 if (solver.NextSolution()) {
00082 CHECK_EQ(s->Value(), 9);
00083 CHECK_EQ(m->Value(), 1);
00084 CHECK_EQ(o->Value(), 0);
00085 CHECK_EQ(e->Value(), 5);
00086 CHECK_EQ(n->Value(), 6);
00087 CHECK_EQ(d->Value(), 7);
00088 CHECK_EQ(r->Value(), 8);
00089 CHECK_EQ(y->Value(), 2);
00090
00091 LG << "S=" << s->Value();
00092 LG << "M=" << m->Value();
00093 LG << "O=" << o->Value();
00094 LG << "E=" << e->Value();
00095 LG << "N=" << n->Value();
00096 LG << "D=" << d->Value();
00097 LG << "R=" << r->Value();
00098 LG << "Y=" << y->Value();
00099 } else {
00100 LG << "Cannot solve problem: number of failures " << solver.failures();
00101 }
00102 solver.EndSearch();
00103 }
00104
00105 }
00106
00107 int main(int argc, char **argv) {
00108 google::ParseCommandLineFlags(&argc, &argv, true);
00109 operations_research::Cryptoarithmetics();
00110 return 0;
00111 }