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

2 months ago
  1. /* PENTOMINO, a geometric placement puzzle */
  2. /* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
  3. /* A pentomino is a plane geometric figure by joining five equal
  4. squares edge to edge. It is a polyomino with five cells. Pentominoes
  5. were defined by Prof. Solomon W. Golomb in his book "Polyominoes:
  6. Puzzles, Patterns, Problems, and Packings."
  7. There are twelve pentominoes, not counting rotations and reflections
  8. as distinct:
  9. +---+
  10. | |
  11. +---+ +---+ +---+
  12. | | | | | |
  13. +---+---+ +---+ +---+ +---+
  14. | | | | | | | | |
  15. +---+---+---+ +---+ +---+ +---+---+
  16. | | | | | | | | | |
  17. +---+---+ +---+ +---+---+ +---+---+
  18. | | | | | | | | |
  19. +---+ +---+ +---+---+ +---+
  20. F I L N
  21. +---+---+ +---+---+---+ +---+
  22. | | | | | | | | |
  23. +---+---+ +---+---+---+ +---+ +---+ +---+
  24. | | | | | | | | | | |
  25. +---+---+ +---+ +---+---+---+ +---+---+---+
  26. | | | | | | | | | | | |
  27. +---+ +---+ +---+---+---+ +---+---+---+
  28. P T U V
  29. +---+
  30. | |
  31. +---+ +---+ +---+---+ +---+---+
  32. | | | | | | | | | |
  33. +---+---+ +---+---+---+ +---+---+ +---+---+
  34. | | | | | | | | | | |
  35. +---+---+---+ +---+---+---+ +---+ +---+---+
  36. | | | | | | | | | |
  37. +---+---+ +---+ +---+ +---+---+
  38. W X Y Z
  39. A classic pentomino puzzle is to tile a given outline, i.e. cover
  40. it without overlap and without gaps. Each of 12 pentominoes has an
  41. area of 5 unit squares, so the outline must have area of 60 units.
  42. Note that it is allowed to rotate and reflect the pentominoes.
  43. (From Wikipedia, the free encyclopedia.) */
  44. set A;
  45. check card(A) = 12;
  46. /* basic set of pentominoes */
  47. set B{a in A};
  48. /* B[a] is a set of distinct versions of pentomino a obtained by its
  49. rotations and reflections */
  50. set C := setof{a in A, b in B[a]} b;
  51. check card(C) = 63;
  52. /* set of distinct versions of all pentominoes */
  53. set D{c in C}, within {0..4} cross {0..4};
  54. /* D[c] is a set of squares (i,j), relative to (0,0), that constitute
  55. a distinct version of pentomino c */
  56. param m, default 6;
  57. /* number of rows in the outline */
  58. param n, default 10;
  59. /* number of columns in the outline */
  60. set R, default {1..m} cross {1..n};
  61. /* set of squares (i,j), relative to (1,1), of the outline to be tiled
  62. with the pentominoes */
  63. check card(R) = 60;
  64. /* the outline must have exactly 60 squares */
  65. set S := setof{c in C, i in 1..m, j in 1..n:
  66. forall{(ii,jj) in D[c]} ((i+ii,j+jj) in R)} (c,i,j);
  67. /* set of all possible placements, where triplet (c,i,j) means that
  68. the base square (0,0) of a distinct version of pentomino c is placed
  69. at square (i,j) of the outline */
  70. var x{(c,i,j) in S}, binary;
  71. /* x[c,i,j] = 1 means that placement (c,i,j) is used in the tiling */
  72. s.t. use{a in A}: sum{(c,i,j) in S: substr(c,1,1) = a} x[c,i,j] = 1;
  73. /* every pentomino must be used exactly once */
  74. s.t. cov{(i,j) in R}:
  75. sum{(c,ii,jj) in S: (i-ii, j-jj) in D[c]} x[c,ii,jj] = 1;
  76. /* every square of the outline must be covered exactly once */
  77. /* this is a feasibility problem, so no objective is needed */
  78. solve;
  79. for {i in 1..m}
  80. { for {j in 1..n}
  81. { for {0..0: (i,j) in R}
  82. { for {(c,ii,jj) in S: (i-ii,j-jj) in D[c] and x[c,ii,jj]}
  83. printf " %s", substr(c,1,1);
  84. }
  85. for {0..0: (i,j) not in R}
  86. printf " .";
  87. }
  88. printf "\n";
  89. }
  90. data;
  91. /* These data correspond to a puzzle from the book "Pentominoes" by
  92. Jon Millington */
  93. param m := 8;
  94. param n := 15;
  95. set R : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 :=
  96. 1 - - - - - - - + - - - - - - -
  97. 2 - - - - - - + + + - - - - - -
  98. 3 - - - - - + + + + + - - - - -
  99. 4 - - - - + + + - + + + - - - -
  100. 5 - - - + + + + - + + + + - - -
  101. 6 - - + + + + + - + + + + + - -
  102. 7 - + + + + + + - + + + + + + -
  103. 8 + + + + + + + + + + + + + + + ;
  104. /* DO NOT CHANGE ANY DATA BELOW! */
  105. set A := F, I, L, N, P, T, U, V, W, X, Y, Z;
  106. set B[F] := F1, F2, F3, F4, F5, F6, F7, F8;
  107. set B[I] := I1, I2;
  108. set B[L] := L1, L2, L3, L4, L5, L6, L7, L8;
  109. set B[N] := N1, N2, N3, N4, N5, N6, N7, N8;
  110. set B[P] := P1, P2, P3, P4, P5, P6, P7, P8;
  111. set B[T] := T1, T2, T3, T4;
  112. set B[U] := U1, U2, U3, U4;
  113. set B[V] := V1, V2, V3, V4;
  114. set B[W] := W1, W2, W3, W4;
  115. set B[X] := X;
  116. set B[Y] := Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8;
  117. set B[Z] := Z1, Z2, Z3, Z4;
  118. set D[F1] : 0 1 2 :=
  119. 0 - + +
  120. 1 + + -
  121. 2 - + - ;
  122. set D[F2] : 0 1 2 :=
  123. 0 - + -
  124. 1 + + +
  125. 2 - - + ;
  126. set D[F3] : 0 1 2 :=
  127. 0 - + -
  128. 1 - + +
  129. 2 + + - ;
  130. set D[F4] : 0 1 2 :=
  131. 0 + - -
  132. 1 + + +
  133. 2 - + - ;
  134. set D[F5] : 0 1 2 :=
  135. 0 + + -
  136. 1 - + +
  137. 2 - + - ;
  138. set D[F6] : 0 1 2 :=
  139. 0 - - +
  140. 1 + + +
  141. 2 - + - ;
  142. set D[F7] : 0 1 2 :=
  143. 0 - + -
  144. 1 + + -
  145. 2 - + + ;
  146. set D[F8] : 0 1 2 :=
  147. 0 - + -
  148. 1 + + +
  149. 2 + - - ;
  150. set D[I1] : 0 :=
  151. 0 +
  152. 1 +
  153. 2 +
  154. 3 +
  155. 4 + ;
  156. set D[I2] : 0 1 2 3 4 :=
  157. 0 + + + + + ;
  158. set D[L1] : 0 1 :=
  159. 0 + -
  160. 1 + -
  161. 2 + -
  162. 3 + + ;
  163. set D[L2] : 0 1 2 3 :=
  164. 0 + + + +
  165. 1 + - - - ;
  166. set D[L3] : 0 1 :=
  167. 0 + +
  168. 1 - +
  169. 2 - +
  170. 3 - + ;
  171. set D[L4] : 0 1 2 3 :=
  172. 0 - - - +
  173. 1 + + + + ;
  174. set D[L5] : 0 1 :=
  175. 0 - +
  176. 1 - +
  177. 2 - +
  178. 3 + + ;
  179. set D[L6] : 0 1 2 3 :=
  180. 0 + - - -
  181. 1 + + + + ;
  182. set D[L7] : 0 1 :=
  183. 0 + +
  184. 1 + -
  185. 2 + -
  186. 3 + - ;
  187. set D[L8] : 0 1 2 3 :=
  188. 0 + + + +
  189. 1 - - - + ;
  190. set D[N1] : 0 1 :=
  191. 0 + -
  192. 1 + -
  193. 2 + +
  194. 3 - + ;
  195. set D[N2] : 0 1 2 3 :=
  196. 0 - + + +
  197. 1 + + - - ;
  198. set D[N3] : 0 1 :=
  199. 0 + -
  200. 1 + +
  201. 2 - +
  202. 3 - + ;
  203. set D[N4] : 0 1 2 3 :=
  204. 0 - - + +
  205. 1 + + + - ;
  206. set D[N5] : 0 1 :=
  207. 0 - +
  208. 1 - +
  209. 2 + +
  210. 3 + - ;
  211. set D[N6] : 0 1 2 3 :=
  212. 0 + + - -
  213. 1 - + + + ;
  214. set D[N7] : 0 1 :=
  215. 0 - +
  216. 1 + +
  217. 2 + -
  218. 3 + - ;
  219. set D[N8] : 0 1 2 3 :=
  220. 0 + + + -
  221. 1 - - + + ;
  222. set D[P1] : 0 1 :=
  223. 0 + +
  224. 1 + +
  225. 2 + - ;
  226. set D[P2] : 0 1 2 :=
  227. 0 + + +
  228. 1 - + + ;
  229. set D[P3] : 0 1 :=
  230. 0 - +
  231. 1 + +
  232. 2 + + ;
  233. set D[P4] : 0 1 2 :=
  234. 0 + + -
  235. 1 + + + ;
  236. set D[P5] : 0 1 :=
  237. 0 + +
  238. 1 + +
  239. 2 - + ;
  240. set D[P6] : 0 1 2 :=
  241. 0 - + +
  242. 1 + + + ;
  243. set D[P7] : 0 1 :=
  244. 0 + -
  245. 1 + +
  246. 2 + + ;
  247. set D[P8] : 0 1 2 :=
  248. 0 + + +
  249. 1 + + - ;
  250. set D[T1] : 0 1 2 :=
  251. 0 + + +
  252. 1 - + -
  253. 2 - + - ;
  254. set D[T2] : 0 1 2 :=
  255. 0 - - +
  256. 1 + + +
  257. 2 - - + ;
  258. set D[T3] : 0 1 2 :=
  259. 0 - + -
  260. 1 - + -
  261. 2 + + + ;
  262. set D[T4] : 0 1 2 :=
  263. 0 + - -
  264. 1 + + +
  265. 2 + - - ;
  266. set D[U1] : 0 1 2 :=
  267. 0 + - +
  268. 1 + + + ;
  269. set D[U2] : 0 1 :=
  270. 0 + +
  271. 1 + -
  272. 2 + + ;
  273. set D[U3] : 0 1 2 :=
  274. 0 + + +
  275. 1 + - + ;
  276. set D[U4] : 0 1 :=
  277. 0 + +
  278. 1 - +
  279. 2 + + ;
  280. set D[V1] : 0 1 2 :=
  281. 0 - - +
  282. 1 - - +
  283. 2 + + + ;
  284. set D[V2] : 0 1 2 :=
  285. 0 + - -
  286. 1 + - -
  287. 2 + + + ;
  288. set D[V3] : 0 1 2 :=
  289. 0 + + +
  290. 1 + - -
  291. 2 + - - ;
  292. set D[V4] : 0 1 2 :=
  293. 0 + + +
  294. 1 - - +
  295. 2 - - + ;
  296. set D[W1] : 0 1 2 :=
  297. 0 - - +
  298. 1 - + +
  299. 2 + + - ;
  300. set D[W2] : 0 1 2 :=
  301. 0 + - -
  302. 1 + + -
  303. 2 - + + ;
  304. set D[W3] : 0 1 2 :=
  305. 0 - + +
  306. 1 + + -
  307. 2 + - - ;
  308. set D[W4] : 0 1 2 :=
  309. 0 + + -
  310. 1 - + +
  311. 2 - - + ;
  312. set D[X] : 0 1 2 :=
  313. 0 - + -
  314. 1 + + +
  315. 2 - + - ;
  316. set D[Y1] : 0 1 :=
  317. 0 + -
  318. 1 + -
  319. 2 + +
  320. 3 + - ;
  321. set D[Y2] : 0 1 2 3 :=
  322. 0 + + + +
  323. 1 - + - - ;
  324. set D[Y3] : 0 1 :=
  325. 0 - +
  326. 1 + +
  327. 2 - +
  328. 3 - + ;
  329. set D[Y4] : 0 1 2 3 :=
  330. 0 - - + -
  331. 1 + + + + ;
  332. set D[Y5] : 0 1 :=
  333. 0 - +
  334. 1 - +
  335. 2 + +
  336. 3 - + ;
  337. set D[Y6] : 0 1 2 3 :=
  338. 0 - + - -
  339. 1 + + + + ;
  340. set D[Y7] : 0 1 :=
  341. 0 + -
  342. 1 + +
  343. 2 + -
  344. 3 + - ;
  345. set D[Y8] : 0 1 2 3 :=
  346. 0 + + + +
  347. 1 - - + - ;
  348. set D[Z1] : 0 1 2 :=
  349. 0 - + +
  350. 1 - + -
  351. 2 + + - ;
  352. set D[Z2] : 0 1 2 :=
  353. 0 + - -
  354. 1 + + +
  355. 2 - - + ;
  356. set D[Z3] : 0 1 2 :=
  357. 0 + + -
  358. 1 - + -
  359. 2 - + + ;
  360. set D[Z4] : 0 1 2 :=
  361. 0 - - +
  362. 1 + + +
  363. 2 + - - ;
  364. end;