-
Notifications
You must be signed in to change notification settings - Fork 0
/
send_more_money.ex
50 lines (41 loc) · 1.27 KB
/
send_more_money.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
defmodule CPSolver.Examples.SendMoreMoney do
@moduledoc """
The classic "cryptarithmetic" (https://en.wikipedia.org/wiki/Verbal_arithmetic) problem.
Solve the following (each letter is a separate digit):
SEND + MORE = MONEY
"""
alias CPSolver.IntVariable, as: Variable
alias CPSolver.Model
alias CPSolver.Constraint.Sum
alias CPSolver.Constraint.AllDifferent.FWC, as: AllDifferent
import CPSolver.Variable.View.Factory
def model() do
letters = [S, E, N, D, M, O, R, Y]
variables =
[s, e, n, d, m, o, r, y] =
Enum.map(letters, fn letter ->
d = (letter in [S, M] && 1..9) || 0..9
Variable.new(d, name: letter)
end)
sum_constraint =
Sum.new(y, [
d,
mul(n, -90),
mul(e, 91),
mul(s, 1000),
mul(r, 10),
mul(o, -900),
mul(m, -9_000)
])
Model.new(variables, [sum_constraint, AllDifferent.new(variables)])
end
def solve() do
{:ok, res} = CPSolver.solve_sync(model(), stop_on: {:max_solutions, 1})
Enum.zip(res.variables, hd(res.solutions))
end
def check_solution([s, e, n, d, m, o, r, y] = _solution) do
1000 * s + 100 * e + 10 * n + d +
1000 * m + 100 * o + 10 * r + e ==
10_000 * m + 1000 * o + 100 * n + 10 * e + y
end
end