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.

84 lines
2.5 KiB

  1. /* Numbrix, Number Placement Puzzle */
  2. /* Written in GNU MathProg by Robert Wood <rwood@targus.com> */
  3. /* Numbrix is a logic-based number-placement puzzle.[1]
  4. * The objective is to fill the grid so that each cell contains
  5. * digits in sequential order taking a horizontal or vertical
  6. * path; diagonal paths are not allowed. The puzzle setter
  7. * provides a grid often with the outer most cells completed.
  8. *
  9. * Completed Numbrix puzzles are usually a square of numbers
  10. * in order from 1 to 64 (8x8 grid) or from 1 to 81 (9x9 grid),
  11. * following a continuous path in sequence.
  12. *
  13. * The modern puzzle was invented by Marilyn vos Savant in 2008
  14. * and published by Parade Magazine under the name "Numbrix",
  15. * near her weekly Ask Marilyn article.
  16. *
  17. * http://en.wikipedia.org/wiki/Numbrix */
  18. set I := {1..9};
  19. set J := {1..9};
  20. set VALS := {1..81};
  21. param givens{I, J}, integer, >= 0, <= 81, default 0;
  22. /* the "givens" */
  23. param neighbors{i in I,j in J, i2 in I, j2 in J} , binary :=
  24. (if abs(i - i2) + abs(j -j2) == 1 then
  25. 1
  26. else
  27. 0
  28. );
  29. /* defines which spots are the boards are neighbors */
  30. var x{i in I, j in J, k in VALS}, binary;
  31. /* x[i,j,k] = 1 means cell [i,j] is assigned number k */
  32. s.t. fa{i in I, j in J, k in VALS: givens[i,j] != 0}:
  33. x[i,j,k] = (if givens[i,j] = k then 1 else 0);
  34. /* assign pre-defined numbers using the "givens" */
  35. s.t. fb{i in I, j in J}: sum{k in VALS} x[i,j,k] = 1;
  36. /* each cell must be assigned exactly one number */
  37. s.t. singleNum {k in VALS}: sum{i in I, j in J} x[i,j,k] = 1;
  38. /* a value can only occur once */
  39. s.t. neighborContraint {i in I, j in J, k in 1..80}:
  40. x[i,j,k] <= sum{i2 in I, j2 in J} x[i2,j2,k+1] * neighbors[i,j,i2,j2];
  41. /* each cell must have a neighbor with the next higher value */
  42. /* there is no need for an objective function here */
  43. solve;
  44. for {i in I}
  45. { for {0..0: i = 1 or i = 4 or i = 7}
  46. printf " +----------+----------+----------+\n";
  47. for {j in J}
  48. { for {0..0: j = 1 or j = 4 or j = 7} printf(" |");
  49. printf " %2d", sum{k in VALS} x[i,j,k] * k;
  50. for {0..0: j = 9} printf(" |\n");
  51. }
  52. for {0..0: i = 9}
  53. printf " +----------+----------+----------+\n";
  54. }
  55. data;
  56. param givens : 1 2 3 4 5 6 7 8 9 :=
  57. 1 . . . . . . . . .
  58. 2 . 11 12 15 18 21 62 61 .
  59. 3 . 6 . . . . . 60 .
  60. 4 . 33 . . . . . 57 .
  61. 5 . 32 . . . . . 56 .
  62. 6 . 37 . . . . . 73 .
  63. 7 . 38 . . . . . 72 .
  64. 8 . 43 44 47 48 51 76 77 .
  65. 9 . . . . . . . . . ;
  66. end;