# # Seseman problem in Elixir. # # Description of the problem: # # n is the length of a border # There are (n-2)^2 "holes", i.e. # there are n^2 - (n-2)^2 variables to find out. # # The simplest problem, n = 3 (n x n matrix) # which is represented by the following matrix: # # a b c # d e # f g h # # Where the following constraints must hold: # # a + b + c = border_sum # a + d + f = border_sum # c + e + h = border_sum # f + g + h = border_sum # a + b + c + d + e + f = total_sum # # For a (Swedish) discussion of this problem, see # "Sesemans matematiska klosterproblem samt lite Constraint Logic Programming" # http://www.hakank.org/webblogg/archives/001084.html # and # Seseman's Convent Problem: http://www.hakank.org/seseman/seseman.cgi # (using ECLiPSe CLP code) # # It was also is commented in the (Swedish) blog post # "Constraint Programming: Minizinc, Gecode/flatzinc och ECLiPSe/minizinc" # http://www.hakank.org/webblogg/archives/001209.html # # It should be 85 solutions. And it does: # # 5 2 2 # 3 3 # 1 4 4 # # 5 1 3 # 1 5 # 3 5 1 # # 4 2 3 # 1 5 # 4 4 1 # # 3 2 4 # 2 4 # 4 4 1 # # ... # # # This program was created by Hakan Kjellerstrand, hakank@gmail.com # See also my Elixir page: http://www.hakank.org/elxir/ # ## Boris Okner: modified to sync with the latest API, ## change naming and result handling. ## defmodule CPSolver.Examples.Hakank.Seseman do # import Enum # Conflicts with CPSolver.Constraint.Factory.sum # import Hakank.CPUtils alias CPSolver.IntVariable alias CPSolver.Constraint.Sum # alias CPSolver.Constraint.Equal alias CPSolver.Model # import CPSolver.Constraint.Factory # import CPSolver.Variable.View.Factory def print_solution(x) do :io.format("~w ~w ~w~n~w ~w~n~w ~w ~w~n~n", x) end def run() do Logger.configure(level: :info) rowsum = 9 total = 24 # It should be 84 solutions # Decision variables x = Enum.map(0..7,fn i -> IntVariable.new(1..9, name: "x[#{i}]") end) [a,b,c, d, e, f,g,h] = x # The different sums that should add to rowsum ts = [ [a,b,c], [a,d,f], [c,e,h], [f,g,h] ] row_sum_constraints = for t <- ts, do: Sum.new(rowsum,t) total_constraint = Sum.new(total,x) model = Model.new(x, [total_constraint | row_sum_constraints ] ) {:ok, result} = CPSolver.solve(model, search: {:first_fail, :indomain_max}, # stop_on: {:max_solutions, 3}, # It should be 85 solutions timeout: :infinity, space_threads: 12 ) result.solutions |> Enum.map(fn s -> s |> Enum.take(8) |> print_solution end) IO.inspect(result.statistics) end end