1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/examples/numbrix.mod Mon Dec 06 13:09:21 2010 +0100
1.3 @@ -0,0 +1,84 @@
1.4 +/* Numbrix, Number Placement Puzzle */
1.5 +
1.6 +/* Written in GNU MathProg by Robert Wood <rwood@targus.com> */
1.7 +
1.8 +/* Numbrix is a logic-based number-placement puzzle.[1]
1.9 + * The objective is to fill the grid so that each cell contains
1.10 + * digits in sequential order taking a horizontal or vertical
1.11 + * path; diagonal paths are not allowed. The puzzle setter
1.12 + * provides a grid often with the outer most cells completed.
1.13 + *
1.14 + * Completed Numbrix puzzles are usually a square of numbers
1.15 + * in order from 1 to 64 (8x8 grid) or from 1 to 81 (9x9 grid),
1.16 + * following a continuous path in sequence.
1.17 + *
1.18 + * The modern puzzle was invented by Marilyn vos Savant in 2008
1.19 + * and published by Parade Magazine under the name "Numbrix",
1.20 + * near her weekly Ask Marilyn article.
1.21 + *
1.22 + * http://en.wikipedia.org/wiki/Numbrix */
1.23 +
1.24 +set I := {1..9};
1.25 +set J := {1..9};
1.26 +set VALS := {1..81};
1.27 +
1.28 +param givens{I, J}, integer, >= 0, <= 81, default 0;
1.29 +/* the "givens" */
1.30 +
1.31 +param neighbors{i in I,j in J, i2 in I, j2 in J} , binary :=
1.32 +(if abs(i - i2) + abs(j -j2) == 1 then
1.33 + 1
1.34 + else
1.35 + 0
1.36 +);
1.37 +/* defines which spots are the boards are neighbors */
1.38 +
1.39 +var x{i in I, j in J, k in VALS}, binary;
1.40 +/* x[i,j,k] = 1 means cell [i,j] is assigned number k */
1.41 +
1.42 +s.t. fa{i in I, j in J, k in VALS: givens[i,j] != 0}:
1.43 + x[i,j,k] = (if givens[i,j] = k then 1 else 0);
1.44 +/* assign pre-defined numbers using the "givens" */
1.45 +
1.46 +s.t. fb{i in I, j in J}: sum{k in VALS} x[i,j,k] = 1;
1.47 +/* each cell must be assigned exactly one number */
1.48 +
1.49 +s.t. singleNum {k in VALS}: sum{i in I, j in J} x[i,j,k] = 1;
1.50 +/* a value can only occur once */
1.51 +
1.52 +s.t. neighborContraint {i in I, j in J, k in 1..80}:
1.53 + x[i,j,k] <= sum{i2 in I, j2 in J} x[i2,j2,k+1] * neighbors[i,j,i2,j2];
1.54 +/* each cell must have a neighbor with the next higher value */
1.55 +
1.56 +
1.57 +/* there is no need for an objective function here */
1.58 +
1.59 +
1.60 +solve;
1.61 +
1.62 +for {i in I}
1.63 +{ for {0..0: i = 1 or i = 4 or i = 7}
1.64 + printf " +----------+----------+----------+\n";
1.65 + for {j in J}
1.66 + { for {0..0: j = 1 or j = 4 or j = 7} printf(" |");
1.67 + printf " %2d", sum{k in VALS} x[i,j,k] * k;
1.68 + for {0..0: j = 9} printf(" |\n");
1.69 + }
1.70 + for {0..0: i = 9}
1.71 + printf " +----------+----------+----------+\n";
1.72 +}
1.73 +
1.74 +data;
1.75 +
1.76 +param givens : 1 2 3 4 5 6 7 8 9 :=
1.77 + 1 . . . . . . . . .
1.78 + 2 . 11 12 15 18 21 62 61 .
1.79 + 3 . 6 . . . . . 60 .
1.80 + 4 . 33 . . . . . 57 .
1.81 + 5 . 32 . . . . . 56 .
1.82 + 6 . 37 . . . . . 73 .
1.83 + 7 . 38 . . . . . 72 .
1.84 + 8 . 43 44 47 48 51 76 77 .
1.85 + 9 . . . . . . . . . ;
1.86 +
1.87 +end;