Guest User

Untitled

a guest
May 26th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.65 KB | None | 0 0
  1. /* A classical Dancing Links Sudoku solver. */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <setjmp.h>
  5.  
  6. // Dancing links Algorithm X exactly from Knuth's paper.
  7.  
  8. typedef struct data {
  9. struct data *l, *r, *u, *d;
  10. struct column *c;
  11. int nRow;
  12. } DATA;
  13.  
  14. typedef struct column {
  15. DATA data[1];
  16. int size;
  17. int nCol;
  18. } COLUMN;
  19.  
  20. typedef struct solution {
  21. struct solution *prev;
  22. DATA *data;
  23. } SOLUTION;
  24.  
  25. static void init(DATA *p, COLUMN *c, int nRow) {
  26. p->u = p->d = p->l = p->r = p;
  27. p->c = c;
  28. p->nRow = nRow;
  29. }
  30.  
  31. static void pushLeft(DATA *p, DATA *r) {
  32. p->l = r->l;
  33. p->r = r;
  34. r->l = p;
  35. p->l->r = p;
  36. }
  37.  
  38. static void pushAbove(DATA *p, DATA *b) {
  39. p->u = b->u;
  40. p->d = b;
  41. b->u = p;
  42. p->u->d = p;
  43. }
  44.  
  45. static void insertFirst(DATA *p, COLUMN *c, int nRow) {
  46. init(p, c, nRow);
  47. pushAbove(p, c->data);
  48. ++c->size;
  49. }
  50.  
  51. static void insert(DATA *p, COLUMN *c, int nRow, DATA *r) {
  52. init(p, c, nRow);
  53. pushLeft(p, r);
  54. pushAbove(p, c->data);
  55. ++c->size;
  56. }
  57.  
  58. static void initColumn(COLUMN *p, int nCol, COLUMN *r) {
  59. p->size = 0;
  60. p->nCol = nCol;
  61. init(p->data, p, -1);
  62. pushLeft(p->data, r->data);
  63. }
  64.  
  65. static void cover(DATA *c) {
  66. c->r->l = c->l;
  67. c->l->r = c->r;
  68. DATA *i = c->d;
  69. while (i != c) {
  70. DATA *j = i->r;
  71. while (j != i) {
  72. j->d->u = j->u;
  73. j->u->d = j->d;
  74. --j->c->size;
  75. j = j->r;
  76. }
  77. i = i->d;
  78. }
  79. }
  80.  
  81. static void uncover(DATA *c) {
  82. DATA *i = c->u;
  83. while (i != c) {
  84. DATA *j = i->l;
  85. while (j != i) {
  86. --j->c->size;
  87. j->d->u = j;
  88. j->u->d = j;
  89. j = j->l;
  90. }
  91. i = i->u;
  92. }
  93. c->r->l = c;
  94. c->l->r = c;
  95. }
  96.  
  97. static DATA *chooseNextColumn(DATA *h) {
  98. DATA *p = h->r;
  99. DATA *p_min = p;
  100. while (p != h) {
  101. if (p->c->size < p_min->c->size) p_min = p;
  102. p = p->r;
  103. }
  104. return p_min;
  105. }
  106.  
  107. // A C-ified closure for the function called to emit a solution.
  108. typedef struct emitter {
  109. void (*emit)(SOLUTION*, struct emitter*);
  110. } EMITTER;
  111.  
  112. static void search(DATA *h, SOLUTION *s, EMITTER *emitter) {
  113. if (h->r == h) {
  114. emitter->emit(s, emitter);
  115. return;
  116. }
  117. DATA *c = chooseNextColumn(h);
  118. cover(c);
  119. DATA *r = c->d;
  120. while (r != c) {
  121. DATA *j = r->r;
  122. while (j != r) {
  123. cover(j->c->data);
  124. j = j->r;
  125. }
  126. SOLUTION sNew[1] = {{ s, r }};
  127. search(h, sNew, emitter);
  128. c = r->c->data;
  129. j = r->l;
  130. while (j != r) {
  131. uncover(j->c->data);
  132. j = j->l;
  133. }
  134. r = r->d;
  135. }
  136. uncover(c);
  137. }
  138.  
  139. // Set up the general purpose Algorithm X constraint solver with a Sudoku problem.
  140.  
  141. // Row and column number encoders.
  142. #define S(X, Y) (((X) * 9) + (Y))
  143. #define RCV(R, C, V) S(S(R, C), V)
  144. #define OFS(N) ((N) * 9 * 9)
  145. #define RC(R, C) (S(R, C) + OFS(0))
  146. #define RV(R, V) (S(R, V) + OFS(1))
  147. #define CV(C, V) (S(C, V) + OFS(2))
  148. #define BV(B, V) (S(B, V) + OFS(3))
  149. #define BLK(I, J) ((((I) % 9) / 3) * 3 + ((J) % 9) / 3)
  150.  
  151. #define SIZE(A) (sizeof A / sizeof A[0])
  152.  
  153. // With this decl, C guarantees that casting EMITTER* to SUDOKU_EMITTER* does the right thing.
  154. typedef struct sudoku_emitter {
  155. EMITTER emitter[1];
  156. char **board;
  157. jmp_buf done;
  158. } SUDOKU_EMITTER;
  159.  
  160. static void emitSudokuSoln(SOLUTION *s, EMITTER *e) {
  161. SUDOKU_EMITTER *se = (SUDOKU_EMITTER*) e;
  162. while (s) {
  163. int rcv = s->data->nRow; // nRow is encoded Sudoku row, column, value
  164. se->board[rcv / 81][rcv / 9 % 9] = '1' + rcv % 9;
  165. s = s->prev;
  166. }
  167. longjmp(se->done, 1);
  168. }
  169.  
  170. static void solveSudoku(char **board) {
  171. // Set up the header.
  172. COLUMN h[1];
  173. init(h->data, h, -1);
  174. h->size = h->nCol = -1;
  175.  
  176. // Set up columns.
  177. COLUMN cols[OFS(4)][1];
  178. for (int n = 0; n < SIZE(cols); ++n) initColumn(cols[n], n, h);
  179.  
  180. // Set up the pool of data objects and an allocation pointer.
  181. DATA data[2916][1];
  182. int dp = 0;
  183.  
  184. // Build matrix.
  185. int nRow = 0;
  186. for (int i = 0; i < 9; ++i) {
  187. for (int j = 0; j < 9; ++j) {
  188. for (int v = 0; v < 9; ++v, ++nRow) {
  189. if (board[i][j] == '.' || board[i][j] == v + '1') {
  190. DATA *head = data[dp++];
  191. insertFirst(head, cols[RC(i, j)], nRow);
  192. insert(data[dp++], cols[RV(i, v)], nRow, head);
  193. insert(data[dp++], cols[CV(j, v)], nRow, head);
  194. insert(data[dp++], cols[BV(BLK(i, j), v)], nRow, head);
  195. }
  196. }
  197. }
  198. }
  199. SUDOKU_EMITTER se[1] = {{{emitSudokuSoln}, board }};
  200. if (setjmp(se->done) == 0) search(h->data, NULL, se->emitter);
  201. }
  202.  
  203. int main(void) {
  204. char a[] = ".3.2..4..";
  205. char b[] = "25.1..9.7";
  206. char c[] = ".....9..3";
  207. char d[] = "4..9.26..";
  208. char e[] = "7.......2";
  209. char f[] = "..65.7..1";
  210. char g[] = "5..8.....";
  211. char h[] = "3.8..5.24";
  212. char i[] = "..2..3.8.";
  213. char *board[] = { a, b, c, d, e, f, g, h, i };
  214. solveSudoku(board);
  215. for (int i = 0; i < 9; ++i) printf("%s\n", board[i]);
  216. return 0;
  217. }
Add Comment
Please, Sign In to add comment