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.

107 lines
3.8 KiB

2 months ago
  1. /* A solver for the Japanese number-puzzle Shikaku
  2. * http://en.wikipedia.org/wiki/Shikaku
  3. *
  4. * Sebastian Nowozin <nowozin@gmail.com>, 27th January 2009
  5. */
  6. param ndim := 10;
  7. set rows := 1..ndim;
  8. set rows1 := 1..(ndim+1);
  9. set cols := 1..ndim;
  10. set cols1 := 1..(ndim+1);
  11. param givens{rows, cols}, integer, >= 0, default 0;
  12. /* Set of vertices as (row,col) coordinates */
  13. set V := { (i,j) in { rows, cols }: givens[i,j] != 0 };
  14. /* Set of all feasible boxes of the right size: only this boxes are possible.
  15. * The box contains (i,j) and ranges from (k,l) to (m,n)
  16. */
  17. set B := { (i,j,k,l,m,n) in { V, rows, cols, rows1, cols1 }:
  18. i >= k and i < m and j >= l and j < n and /* Contains (i,j) */
  19. ((m-k)*(n-l)) = givens[i,j] and /* Right size */
  20. card({ (s,t) in V: s >= k and s < m and t >= l and t < n }) = 1
  21. /* Contains only (i,j), no other number */
  22. };
  23. var x{B}, binary;
  24. /* Cover each square exactly once */
  25. s.t. cover_once{ (s,t) in { rows, cols } }:
  26. sum{(i,j,k,l,m,n) in B: s >= k and s < m and t >= l and t < n}
  27. x[i,j,k,l,m,n] = 1;
  28. minimize cost: 0;
  29. solve;
  30. /* Output solution graphically */
  31. printf "\nSolution:\n";
  32. for { row in rows1 } {
  33. for { col in cols1 } {
  34. printf{0..0: card({(i,j,k,l,m,n) in B:
  35. col >= l and col <= n and (row = k or row = m) and
  36. x[i,j,k,l,m,n] = 1}) > 0 and
  37. card({(i,j,k,l,m,n) in B:
  38. row >= k and row <= m and (col = l or col = n) and
  39. x[i,j,k,l,m,n] = 1}) > 0} "+";
  40. printf{0..0: card({(i,j,k,l,m,n) in B:
  41. col >= l and col <= n and (row = k or row = m) and
  42. x[i,j,k,l,m,n] = 1}) = 0 and
  43. card({(i,j,k,l,m,n) in B:
  44. row >= k and row <= m and (col = l or col = n) and
  45. x[i,j,k,l,m,n] = 1}) > 0} "|";
  46. printf{0..0: card({(i,j,k,l,m,n) in B:
  47. row >= k and row <= m and (col = l or col = n) and
  48. x[i,j,k,l,m,n] = 1}) = 0 and
  49. card({(i,j,k,l,m,n) in B:
  50. col >= l and col <= n and (row = k or row = m) and
  51. x[i,j,k,l,m,n] = 1}) > 0} "-";
  52. printf{0..0: card({(i,j,k,l,m,n) in B:
  53. row >= k and row <= m and (col = l or col = n) and
  54. x[i,j,k,l,m,n] = 1}) = 0 and
  55. card({(i,j,k,l,m,n) in B:
  56. col >= l and col <= n and (row = k or row = m) and
  57. x[i,j,k,l,m,n] = 1}) = 0} " ";
  58. printf{0..0: card({(i,j,k,l,m,n) in B:
  59. col >= l and col < n and (row = k or row = m) and
  60. x[i,j,k,l,m,n] = 1}) > 0} "---";
  61. printf{0..0: card({(i,j,k,l,m,n) in B:
  62. col >= l and col < n and (row = k or row = m) and
  63. x[i,j,k,l,m,n] = 1}) = 0} " ";
  64. }
  65. printf "\n";
  66. for { (col,p) in { cols, 1 }: card({ s in rows: s = row }) = 1 } {
  67. printf{0..0: card({(i,j,k,l,m,n) in B:
  68. row >= k and row < m and (col = l or col = n) and
  69. x[i,j,k,l,m,n] = 1}) > 0} "|";
  70. printf{0..0: card({(i,j,k,l,m,n) in B:
  71. row >= k and row < m and (col = l or col = n) and
  72. x[i,j,k,l,m,n] = 1}) = 0} " ";
  73. printf{0..0: card({ (i,j) in V: i = row and j = col}) > 0} " %2d", givens[row,col];
  74. printf{0..0: card({ (i,j) in V: i = row and j = col}) = 0} " .";
  75. }
  76. printf{0..0: card({ r in rows: r = row }) = 1} "|\n";
  77. }
  78. data;
  79. /* This Shikaku is from
  80. * http://www.emn.fr/x-info/sdemasse/gccat/KShikaku.html#uid5449
  81. */
  82. param givens : 1 2 3 4 5 6 7 8 9 10 :=
  83. 1 9 . . . 12 . . 5 . .
  84. 2 . . . . . . . . . .
  85. 3 . . . . . . . . . 6
  86. 4 8 . 6 . 8 . . . . .
  87. 5 . . . . . . . . . .
  88. 6 . . . . . . . . . .
  89. 7 . . . . . 6 . 8 . 12
  90. 8 4 . . . . . . . . .
  91. 9 . . . . . . . . . .
  92. 10 . . 3 . . 9 . . . 4
  93. ;
  94. end;