2.5.1 Sudoku Puzzle (sudokuM)

Run LPL Code  ,  PDF Document

Problem

The Sudoku problerm is explained in another model (see sudoku).

Modeling Steps

The implementation for this model is explained elsewhere (see sudokuInt).

Further Comments

MiniZinc contains and uses the global constraint alldifferent (LPL uses the Alldiff function) to specify the constraints on the integer variables. MiniZinc uses ranges and array to specify multi-dimensional data sets or variables.

LPL code (run sudokuM)

model Sudoku "Sudoku Puzzle"; 
  parameter n:=3; 
  set i,j := 1..n^2; 
  set g,h:=1..n;  u,v:=1..n; 
  integer parameter start{i,j} := [ 
          5, 3, 1, 0, 0, 9, 6, 2, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 6, 0, 9, 4, 
          0, 9, 6, 0, 3, 8, 1, 0, 0, 
          0, 0, 0, 0, 0, 0, 3, 0, 0, 
          7, 0, 0, 6, 0, 1, 0, 4, 0, 
          0, 6, 0, 8, 0, 0, 4, 0, 0, 
          1, 0, 5, 0, 2, 0, 0, 0, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0]; 
  integer variable X{i,j} [1..n^2]; 
  constraint 
    A{i}:   Alldiff({j} X[i,j]); 
    B{j}:   Alldiff({i} X[i,j]); 
    C{g,h}: Alldiff({u,v} X[(g-1)*n+u,(h-1)*n+v]); 
    D{i,j|start}: X[i,j] = start[i,j]; 
  solve; 
  Write{i}('%3d' n',{j} X); 
end

MiniZinc code (download sudokuM.mzn)

set of int: RANGE = 1..9; 
array[RANGE, RANGE] of int: start; 
array[RANGE, RANGE] of var RANGE: X; 
array[RANGE] of RANGE: first_i = [((k-1) div 3)*3 + 1| k in RANGE]; % first i in each square 
array[RANGE] of RANGE: first_j = [((k-1) mod 3)*3 + 1| k in RANGE]; % first j in each square 
start = [| 5, 3, 1, 0, 0, 9, 6, 2, 0, 
         | 0, 0, 0, 0, 0, 0, 0, 0, 0, 
         | 0, 0, 0, 0, 0, 6, 0, 9, 4, 
         | 0, 9, 6, 0, 3, 8, 1, 0, 0, 
         | 0, 0, 0, 0, 0, 0, 3, 0, 0, 
         | 7, 0, 0, 6, 0, 1, 0, 4, 0, 
         | 0, 6, 0, 8, 0, 0, 4, 0, 0, 
         | 1, 0, 5, 0, 2, 0, 0, 0, 0, 
         | 0, 0, 0, 0, 0, 0, 0, 0, 0 |]; 
 
include "alldifferent.mzn"; 
constraint forall(i in RANGE)(alldifferent([X[i,j] | j in RANGE])); 
constraint forall(j in RANGE)(alldifferent([X[i,j] | i in RANGE])); 
constraint forall(k in RANGE)(alldifferent([X[i,j] | i in first_i[k]..first_i[k]+2, j in first_j[k]..first_j[k]+2])); 
constraint forall(i,j in RANGE where start[i,j]!=0) (X[i,j] = start[i,j]); 
 
output [show([X[i,j]| j in RANGE]) ++ "' n"| i in RANGE]; 
 
solve satisfy;