OR-Toolsは便利?
検証中.
ものによって言語別サンプルが無いので,補間.
''' OR-Toolsのサイトには,CP-SAT SolverでのCryptarithmetricが無かったので自作'''
# S E N D
# + ) M O R E
# -----------
# M O N E Y
#
# ANSWER:FISIBLE (最適かは不明)
# 9 5 6 7
# + ) 1 0 8 5
# -----------
# 1 0 6 5 2
#
# 魔法のコトバ
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from ortools.sat.python import cp_model
def SendMoreMoney():
# 問題モデルの宣言
model = cp_model.CpModel()
# 変数の宣言
limit = 9
s = model.NewIntVar(1, limit, 'S')
e = model.NewIntVar(0, limit, 'E')
n = model.NewIntVar(0, limit, 'N')
d = model.NewIntVar(0, limit, 'D')
m = model.NewIntVar(1, limit, 'M')
o = model.NewIntVar(0, limit, 'O')
r = model.NewIntVar(0, limit, 'R')
# e
# m
# o
# n
# e
y = model.NewIntVar(0, limit, 'Y')
# 全ての英語に割り当たる数字が異なるという制約を造るために変数のグループを作る
letters = [s, e, n, d, m, o, r, y]
# 各位を表すのに必要
kBase = 10
# Verify that we have enough digits
assert kBase >= len(letters)
# ソルバに全ての数字が異なるという制約を追加
model.AddAllDifferent(letters)
# 足し算の制約を追加
# SEND + MORE = MONEY
model.Add(s * kBase * kBase * kBase + e * kBase * kBase + n * kBase + d
+ m * kBase * kBase * kBase + o * kBase * kBase + r * kBase + e
== m * kBase * kBase * kBase * kBase + o * kBase * kBase * kBase + n * kBase * kBase + e * kBase + y)
# Solverの宣言
solver = cp_model.CpSolver()
status = solver.Solve(model)
print(solver.StatusName(status))
print('s = %i' % solver.Value(s))
print('e = %i' % solver.Value(e))
print('n = %i' % solver.Value(n))
print('d = %i' % solver.Value(d))
print('m = %i' % solver.Value(m))
print('o = %i' % solver.Value(o))
print('r = %i' % solver.Value(r))
print('y = %i' % solver.Value(y))
SendMoreMoney()