You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
460 lines
10 KiB
460 lines
10 KiB
/* PENTOMINO, a geometric placement puzzle */
|
|
|
|
/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
|
|
|
|
/* A pentomino is a plane geometric figure by joining five equal
|
|
squares edge to edge. It is a polyomino with five cells. Pentominoes
|
|
were defined by Prof. Solomon W. Golomb in his book "Polyominoes:
|
|
Puzzles, Patterns, Problems, and Packings."
|
|
|
|
There are twelve pentominoes, not counting rotations and reflections
|
|
as distinct:
|
|
|
|
+---+
|
|
| |
|
|
+---+ +---+ +---+
|
|
| | | | | |
|
|
+---+---+ +---+ +---+ +---+
|
|
| | | | | | | | |
|
|
+---+---+---+ +---+ +---+ +---+---+
|
|
| | | | | | | | | |
|
|
+---+---+ +---+ +---+---+ +---+---+
|
|
| | | | | | | | |
|
|
+---+ +---+ +---+---+ +---+
|
|
F I L N
|
|
|
|
+---+---+ +---+---+---+ +---+
|
|
| | | | | | | | |
|
|
+---+---+ +---+---+---+ +---+ +---+ +---+
|
|
| | | | | | | | | | |
|
|
+---+---+ +---+ +---+---+---+ +---+---+---+
|
|
| | | | | | | | | | | |
|
|
+---+ +---+ +---+---+---+ +---+---+---+
|
|
P T U V
|
|
|
|
+---+
|
|
| |
|
|
+---+ +---+ +---+---+ +---+---+
|
|
| | | | | | | | | |
|
|
+---+---+ +---+---+---+ +---+---+ +---+---+
|
|
| | | | | | | | | | |
|
|
+---+---+---+ +---+---+---+ +---+ +---+---+
|
|
| | | | | | | | | |
|
|
+---+---+ +---+ +---+ +---+---+
|
|
W X Y Z
|
|
|
|
|
|
A classic pentomino puzzle is to tile a given outline, i.e. cover
|
|
it without overlap and without gaps. Each of 12 pentominoes has an
|
|
area of 5 unit squares, so the outline must have area of 60 units.
|
|
Note that it is allowed to rotate and reflect the pentominoes.
|
|
|
|
(From Wikipedia, the free encyclopedia.) */
|
|
|
|
set A;
|
|
check card(A) = 12;
|
|
/* basic set of pentominoes */
|
|
|
|
set B{a in A};
|
|
/* B[a] is a set of distinct versions of pentomino a obtained by its
|
|
rotations and reflections */
|
|
|
|
set C := setof{a in A, b in B[a]} b;
|
|
check card(C) = 63;
|
|
/* set of distinct versions of all pentominoes */
|
|
|
|
set D{c in C}, within {0..4} cross {0..4};
|
|
/* D[c] is a set of squares (i,j), relative to (0,0), that constitute
|
|
a distinct version of pentomino c */
|
|
|
|
param m, default 6;
|
|
/* number of rows in the outline */
|
|
|
|
param n, default 10;
|
|
/* number of columns in the outline */
|
|
|
|
set R, default {1..m} cross {1..n};
|
|
/* set of squares (i,j), relative to (1,1), of the outline to be tiled
|
|
with the pentominoes */
|
|
|
|
check card(R) = 60;
|
|
/* the outline must have exactly 60 squares */
|
|
|
|
set S := setof{c in C, i in 1..m, j in 1..n:
|
|
forall{(ii,jj) in D[c]} ((i+ii,j+jj) in R)} (c,i,j);
|
|
/* set of all possible placements, where triplet (c,i,j) means that
|
|
the base square (0,0) of a distinct version of pentomino c is placed
|
|
at square (i,j) of the outline */
|
|
|
|
var x{(c,i,j) in S}, binary;
|
|
/* x[c,i,j] = 1 means that placement (c,i,j) is used in the tiling */
|
|
|
|
s.t. use{a in A}: sum{(c,i,j) in S: substr(c,1,1) = a} x[c,i,j] = 1;
|
|
/* every pentomino must be used exactly once */
|
|
|
|
s.t. cov{(i,j) in R}:
|
|
sum{(c,ii,jj) in S: (i-ii, j-jj) in D[c]} x[c,ii,jj] = 1;
|
|
/* every square of the outline must be covered exactly once */
|
|
|
|
/* this is a feasibility problem, so no objective is needed */
|
|
|
|
solve;
|
|
|
|
for {i in 1..m}
|
|
{ for {j in 1..n}
|
|
{ for {0..0: (i,j) in R}
|
|
{ for {(c,ii,jj) in S: (i-ii,j-jj) in D[c] and x[c,ii,jj]}
|
|
printf " %s", substr(c,1,1);
|
|
}
|
|
for {0..0: (i,j) not in R}
|
|
printf " .";
|
|
}
|
|
printf "\n";
|
|
}
|
|
|
|
data;
|
|
|
|
/* These data correspond to a puzzle from the book "Pentominoes" by
|
|
Jon Millington */
|
|
|
|
param m := 8;
|
|
|
|
param n := 15;
|
|
|
|
set R : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 :=
|
|
1 - - - - - - - + - - - - - - -
|
|
2 - - - - - - + + + - - - - - -
|
|
3 - - - - - + + + + + - - - - -
|
|
4 - - - - + + + - + + + - - - -
|
|
5 - - - + + + + - + + + + - - -
|
|
6 - - + + + + + - + + + + + - -
|
|
7 - + + + + + + - + + + + + + -
|
|
8 + + + + + + + + + + + + + + + ;
|
|
|
|
/* DO NOT CHANGE ANY DATA BELOW! */
|
|
|
|
set A := F, I, L, N, P, T, U, V, W, X, Y, Z;
|
|
|
|
set B[F] := F1, F2, F3, F4, F5, F6, F7, F8;
|
|
set B[I] := I1, I2;
|
|
set B[L] := L1, L2, L3, L4, L5, L6, L7, L8;
|
|
set B[N] := N1, N2, N3, N4, N5, N6, N7, N8;
|
|
set B[P] := P1, P2, P3, P4, P5, P6, P7, P8;
|
|
set B[T] := T1, T2, T3, T4;
|
|
set B[U] := U1, U2, U3, U4;
|
|
set B[V] := V1, V2, V3, V4;
|
|
set B[W] := W1, W2, W3, W4;
|
|
set B[X] := X;
|
|
set B[Y] := Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8;
|
|
set B[Z] := Z1, Z2, Z3, Z4;
|
|
|
|
set D[F1] : 0 1 2 :=
|
|
0 - + +
|
|
1 + + -
|
|
2 - + - ;
|
|
|
|
set D[F2] : 0 1 2 :=
|
|
0 - + -
|
|
1 + + +
|
|
2 - - + ;
|
|
|
|
set D[F3] : 0 1 2 :=
|
|
0 - + -
|
|
1 - + +
|
|
2 + + - ;
|
|
|
|
set D[F4] : 0 1 2 :=
|
|
0 + - -
|
|
1 + + +
|
|
2 - + - ;
|
|
|
|
set D[F5] : 0 1 2 :=
|
|
0 + + -
|
|
1 - + +
|
|
2 - + - ;
|
|
|
|
set D[F6] : 0 1 2 :=
|
|
0 - - +
|
|
1 + + +
|
|
2 - + - ;
|
|
|
|
set D[F7] : 0 1 2 :=
|
|
0 - + -
|
|
1 + + -
|
|
2 - + + ;
|
|
|
|
set D[F8] : 0 1 2 :=
|
|
0 - + -
|
|
1 + + +
|
|
2 + - - ;
|
|
|
|
set D[I1] : 0 :=
|
|
0 +
|
|
1 +
|
|
2 +
|
|
3 +
|
|
4 + ;
|
|
|
|
set D[I2] : 0 1 2 3 4 :=
|
|
0 + + + + + ;
|
|
|
|
set D[L1] : 0 1 :=
|
|
0 + -
|
|
1 + -
|
|
2 + -
|
|
3 + + ;
|
|
|
|
set D[L2] : 0 1 2 3 :=
|
|
0 + + + +
|
|
1 + - - - ;
|
|
|
|
set D[L3] : 0 1 :=
|
|
0 + +
|
|
1 - +
|
|
2 - +
|
|
3 - + ;
|
|
|
|
set D[L4] : 0 1 2 3 :=
|
|
0 - - - +
|
|
1 + + + + ;
|
|
|
|
set D[L5] : 0 1 :=
|
|
0 - +
|
|
1 - +
|
|
2 - +
|
|
3 + + ;
|
|
|
|
set D[L6] : 0 1 2 3 :=
|
|
0 + - - -
|
|
1 + + + + ;
|
|
|
|
set D[L7] : 0 1 :=
|
|
0 + +
|
|
1 + -
|
|
2 + -
|
|
3 + - ;
|
|
|
|
set D[L8] : 0 1 2 3 :=
|
|
0 + + + +
|
|
1 - - - + ;
|
|
|
|
set D[N1] : 0 1 :=
|
|
0 + -
|
|
1 + -
|
|
2 + +
|
|
3 - + ;
|
|
|
|
set D[N2] : 0 1 2 3 :=
|
|
0 - + + +
|
|
1 + + - - ;
|
|
|
|
set D[N3] : 0 1 :=
|
|
0 + -
|
|
1 + +
|
|
2 - +
|
|
3 - + ;
|
|
|
|
set D[N4] : 0 1 2 3 :=
|
|
0 - - + +
|
|
1 + + + - ;
|
|
|
|
set D[N5] : 0 1 :=
|
|
0 - +
|
|
1 - +
|
|
2 + +
|
|
3 + - ;
|
|
|
|
set D[N6] : 0 1 2 3 :=
|
|
0 + + - -
|
|
1 - + + + ;
|
|
|
|
set D[N7] : 0 1 :=
|
|
0 - +
|
|
1 + +
|
|
2 + -
|
|
3 + - ;
|
|
|
|
set D[N8] : 0 1 2 3 :=
|
|
0 + + + -
|
|
1 - - + + ;
|
|
|
|
set D[P1] : 0 1 :=
|
|
0 + +
|
|
1 + +
|
|
2 + - ;
|
|
|
|
set D[P2] : 0 1 2 :=
|
|
0 + + +
|
|
1 - + + ;
|
|
|
|
set D[P3] : 0 1 :=
|
|
0 - +
|
|
1 + +
|
|
2 + + ;
|
|
|
|
set D[P4] : 0 1 2 :=
|
|
0 + + -
|
|
1 + + + ;
|
|
|
|
set D[P5] : 0 1 :=
|
|
0 + +
|
|
1 + +
|
|
2 - + ;
|
|
|
|
set D[P6] : 0 1 2 :=
|
|
0 - + +
|
|
1 + + + ;
|
|
|
|
set D[P7] : 0 1 :=
|
|
0 + -
|
|
1 + +
|
|
2 + + ;
|
|
|
|
set D[P8] : 0 1 2 :=
|
|
0 + + +
|
|
1 + + - ;
|
|
|
|
set D[T1] : 0 1 2 :=
|
|
0 + + +
|
|
1 - + -
|
|
2 - + - ;
|
|
|
|
set D[T2] : 0 1 2 :=
|
|
0 - - +
|
|
1 + + +
|
|
2 - - + ;
|
|
|
|
set D[T3] : 0 1 2 :=
|
|
0 - + -
|
|
1 - + -
|
|
2 + + + ;
|
|
|
|
set D[T4] : 0 1 2 :=
|
|
0 + - -
|
|
1 + + +
|
|
2 + - - ;
|
|
|
|
set D[U1] : 0 1 2 :=
|
|
0 + - +
|
|
1 + + + ;
|
|
|
|
set D[U2] : 0 1 :=
|
|
0 + +
|
|
1 + -
|
|
2 + + ;
|
|
|
|
set D[U3] : 0 1 2 :=
|
|
0 + + +
|
|
1 + - + ;
|
|
|
|
set D[U4] : 0 1 :=
|
|
0 + +
|
|
1 - +
|
|
2 + + ;
|
|
|
|
set D[V1] : 0 1 2 :=
|
|
0 - - +
|
|
1 - - +
|
|
2 + + + ;
|
|
|
|
set D[V2] : 0 1 2 :=
|
|
0 + - -
|
|
1 + - -
|
|
2 + + + ;
|
|
|
|
set D[V3] : 0 1 2 :=
|
|
0 + + +
|
|
1 + - -
|
|
2 + - - ;
|
|
|
|
set D[V4] : 0 1 2 :=
|
|
0 + + +
|
|
1 - - +
|
|
2 - - + ;
|
|
|
|
set D[W1] : 0 1 2 :=
|
|
0 - - +
|
|
1 - + +
|
|
2 + + - ;
|
|
|
|
set D[W2] : 0 1 2 :=
|
|
0 + - -
|
|
1 + + -
|
|
2 - + + ;
|
|
|
|
set D[W3] : 0 1 2 :=
|
|
0 - + +
|
|
1 + + -
|
|
2 + - - ;
|
|
|
|
set D[W4] : 0 1 2 :=
|
|
0 + + -
|
|
1 - + +
|
|
2 - - + ;
|
|
|
|
set D[X] : 0 1 2 :=
|
|
0 - + -
|
|
1 + + +
|
|
2 - + - ;
|
|
|
|
set D[Y1] : 0 1 :=
|
|
0 + -
|
|
1 + -
|
|
2 + +
|
|
3 + - ;
|
|
|
|
set D[Y2] : 0 1 2 3 :=
|
|
0 + + + +
|
|
1 - + - - ;
|
|
|
|
set D[Y3] : 0 1 :=
|
|
0 - +
|
|
1 + +
|
|
2 - +
|
|
3 - + ;
|
|
|
|
set D[Y4] : 0 1 2 3 :=
|
|
0 - - + -
|
|
1 + + + + ;
|
|
|
|
set D[Y5] : 0 1 :=
|
|
0 - +
|
|
1 - +
|
|
2 + +
|
|
3 - + ;
|
|
|
|
set D[Y6] : 0 1 2 3 :=
|
|
0 - + - -
|
|
1 + + + + ;
|
|
|
|
set D[Y7] : 0 1 :=
|
|
0 + -
|
|
1 + +
|
|
2 + -
|
|
3 + - ;
|
|
|
|
set D[Y8] : 0 1 2 3 :=
|
|
0 + + + +
|
|
1 - - + - ;
|
|
|
|
set D[Z1] : 0 1 2 :=
|
|
0 - + +
|
|
1 - + -
|
|
2 + + - ;
|
|
|
|
set D[Z2] : 0 1 2 :=
|
|
0 + - -
|
|
1 + + +
|
|
2 - - + ;
|
|
|
|
set D[Z3] : 0 1 2 :=
|
|
0 + + -
|
|
1 - + -
|
|
2 - + + ;
|
|
|
|
set D[Z4] : 0 1 2 :=
|
|
0 - - +
|
|
1 + + +
|
|
2 + - - ;
|
|
|
|
end;
|