/*
Model name : gunport4.mod
Description : solves Gunport puzzles
Source : Martin Gardner
Date written : 28/3/06
Written by : Robert Bosch, Oberlin College
Email : bobb@cs.oberlin.edu
*/
int nbRows = 7;
int nbCols = 9;
int p;
dvar boolean h[1..nbRows,1..nbCols-1];
dvar boolean v[1..nbRows-1,1..nbCols];
dvar boolean m[1..nbRows,1..nbCols];
int m3 = nbRows mod 3;
int n3 = nbCols mod 3;
int fhr;
int shr;
int fhc;
int shc;
execute {
/* compute required number of monominoes */
if (m3*n3==0)
p = nbRows*nbCols/3;
else
if (m3==n3)
p = (nbRows*nbCols-4)/3;
else
p = (nbRows*nbCols-2)/3;
/* compute ranges for symmetry constraints */
fhr = Math.floor(nbRows/2);
if (nbRows % 2 == 0)
shr = fhr+1;
else
shr = fhr+2;
fhc = Math.floor(nbCols/2);
if (nbCols % 2 == 0)
shc = fhc+1;
else
shc = fhc+2;
}
maximize sum(r in 1..nbRows, c in 1..nbCols) m[r,c];
subject to {
/* Interior cells */
forall (r in 2..nbRows-1, c in 2..nbCols-1)
h[r,c-1] + h[r,c] + v[r-1,c] + v[r,c] + m[r,c] == 1;
/* Edge cells, top row */
forall (c in 2..nbCols-1)
h[1,c-1] + h[1,c] + v[1,c] + m[1,c] == 1;
/* Edge cells, bottom row */
forall (c in 2..nbCols-1)
h[nbRows,c-1] + h[nbRows,c] + v[nbRows-1,c] + m[nbRows,c] == 1;
/* Edge cells, leftmost column */
forall (r in 2..nbRows-1)
h[r,1] + v[r-1,1] + v[r,1] + m[r,1] == 1;
/* Edge cells, rightmost column */
forall (r in 2..nbRows-1)
h[r,nbCols-1] + v[r-1,nbCols] + v[r,nbCols] + m[r,nbCols] == 1;
/* Cell (1,1) */
h[1,1] + v[1,1] + m[1,1] == 1;
/* Cell (1,nbCols) */
h[1,nbCols-1] + v[1,nbCols] + m[1,nbCols] == 1;
/* Cell (nbRows,1) */
h[nbRows,1] + v[nbRows-1,1] + m[nbRows,1] == 1;
/* Cell (nbRows,nbCols) */
h[nbRows,nbCols-1] + v[nbRows-1,nbCols] + m[nbRows,nbCols] == 1;
/* No horizontally adjacent monominoes */
forall (r in 1..nbRows, c in 1..nbCols-1)
m[r,c] + m[r,c+1] <= 1;
/* No vertically adjacent monominoes */
forall (r in 1..nbRows-1, c in 1..nbCols)
m[r,c] + m[r+1,c] <= 1;
/* eliminate symmetries */
sum( r in 1..fhr, c in 1..nbCols) m[r,c]
<= sum( r in shr..nbRows, c in 1..nbCols) m[r,c];
sum( r in 1..nbRows, c in 1..fhc) m[r,c]
<= sum( r in 1..nbRows, c in shc..nbCols) m[r,c];
/* place specified number of numbers */
sum(r in 1..nbRows, c in 1..nbCols) m[r,c] == p;
}
|