├── README └── sudoku.c /README: -------------------------------------------------------------------------------- 1 | This is a simple command-line Sudoku solver written in C for mere educational 2 | purposes. It expects a partially solved Sudoku board as input, that will be 3 | read from standard input or the file given as the first program argument, if 4 | given. Then, it will try to solve the board and print it solved on standard 5 | output. 6 | 7 | The input format is simple. The board must be given as cells from top to bottom 8 | and left to right, with empty cells represented by dots and other cells 9 | represented by its value. Example: 10 | 11 | 5 3 . . 7 . . . . 12 | 6 . . 1 9 5 . . . 13 | . 9 8 . . . . 6 . 14 | 8 . . . 6 . . . 3 15 | 4 . . 8 . 3 . . 1 16 | 7 . . . 2 . . . 6 17 | . 6 . . . . 2 8 . 18 | . . . 4 1 9 . . 5 19 | . . . . 8 . . 7 9 20 | 21 | Same example in a more compact format, also valid: 22 | 23 | 53..7.... 24 | 6..195... 25 | .98....6. 26 | 8...6...3 27 | 4..8.3..1 28 | 7...2...6 29 | .6....28. 30 | ...419..5 31 | ....8..79 32 | 33 | -------------------------------------------------------------------------------- /sudoku.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sudoku.c: A simple command-line Sudoku solver in C for educational purposes. 3 | * 4 | * Author: Ricardo Garcia Gonzalez. 5 | * License: Public domain code. 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define SUBDIMENSION (3) 13 | #define MIN_NUM (1) 14 | #define MAX_NUM (9) 15 | #define TOTAL_NUMS (9) 16 | #define ARRAY_SIZE (MIN_NUM + TOTAL_NUMS) 17 | 18 | #ifdef ASSERT 19 | #define assert_(A) assert(A) 20 | #else 21 | #define assert_(A) 22 | #endif 23 | 24 | /* 25 | * 26 | * CANDIDATES. 27 | * 28 | */ 29 | 30 | /* 31 | * A candidates array represents which values have already been used for a row, 32 | * column or square. 33 | */ 34 | typedef int candidates[ARRAY_SIZE]; 35 | 36 | /* 37 | * All candidates start as unused. 38 | */ 39 | void init_candidates(candidates *c) 40 | { 41 | int i; 42 | 43 | for (i = MIN_NUM; i <= MAX_NUM; ++i) 44 | (*c)[i] = 0; 45 | } 46 | 47 | /* 48 | * Using a candidate number means marking it as used in the array. 49 | */ 50 | void use_candidate(candidates *cp, int num) 51 | { 52 | assert_(cp != NULL && num >= MIN_NUM && num <= MAX_NUM); 53 | 54 | (*cp)[num] = 1; 55 | } 56 | 57 | /* 58 | * Restoring a candidate means marking it as unused in the array. 59 | */ 60 | void restore_candidate(candidates *cp, int num) 61 | { 62 | assert_(cp != NULL && num >= MIN_NUM && num <= MAX_NUM); 63 | 64 | (*cp)[num] = 0; 65 | } 66 | 67 | /* 68 | * 69 | * CELLS AND BOARDS. 70 | * 71 | */ 72 | 73 | /* 74 | * A cell has a flag to indicate if its value has been set or not, the cell 75 | * value and three pointers to candidate arrays. One for the row it belongs to, 76 | * one for the column it belongs to and one for the square it belongs to. 77 | */ 78 | struct cell { 79 | int has_value; 80 | int value; 81 | 82 | candidates *row_candidates; 83 | candidates *col_candidates; 84 | candidates *square_candidates; 85 | }; 86 | 87 | /* 88 | * A board has a number of unset cells, a matrix of cells and the candidate 89 | * arrays for each row, column and square in the board. 90 | */ 91 | struct board { 92 | int unset_cells; 93 | struct cell cells[ARRAY_SIZE][ARRAY_SIZE]; 94 | 95 | candidates rows[ARRAY_SIZE]; 96 | candidates columns[ARRAY_SIZE]; 97 | candidates squares[ARRAY_SIZE]; 98 | }; 99 | 100 | /* 101 | * Auxiliar. Calculates the square number for the given cell. Squares are 102 | * numberd from top to bottom, left to right. 103 | */ 104 | int square(int row, int col) 105 | { 106 | assert_(row >= MIN_NUM && row <= MAX_NUM && 107 | col >= MIN_NUM && col <= MAX_NUM); 108 | 109 | return (((row - 1) / SUBDIMENSION) * SUBDIMENSION) + 110 | ((col - 1) / SUBDIMENSION) + 1; 111 | } 112 | 113 | /* 114 | * Every board starts empty. Cell candidate pointers are established. 115 | */ 116 | void init_board(struct board *b) 117 | { 118 | int i; 119 | int j; 120 | 121 | assert_(b != NULL); 122 | 123 | b->unset_cells = TOTAL_NUMS * TOTAL_NUMS; 124 | 125 | for (i = MIN_NUM; i <= MAX_NUM; ++i) { 126 | init_candidates(b->rows + i); 127 | init_candidates(b->columns + i); 128 | init_candidates(b->squares + i); 129 | 130 | for (j = MIN_NUM; j <= MAX_NUM; ++j) { 131 | b->cells[i][j].has_value = 0; 132 | b->cells[i][j].value = 0; 133 | b->cells[i][j].row_candidates = b->rows + i; 134 | b->cells[i][j].col_candidates = b->columns + j; 135 | b->cells[i][j].square_candidates = b->squares + square(i, j); 136 | } 137 | } 138 | } 139 | 140 | /* 141 | * Finds the lowest candidate number which is free in all arrays, having a 142 | * value greater or equal to the "atleast" argument. 143 | */ 144 | int find_common_free(candidates *r, candidates *c, candidates *s, int atleast) 145 | { 146 | assert_(r != NULL && c != NULL && s != NULL); 147 | 148 | int i; 149 | for (i = atleast; i <= MAX_NUM; ++i) 150 | if ((! (*r)[i]) && (! (*c)[i]) && (! (*s)[i])) 151 | return i; 152 | return (-1); 153 | } 154 | 155 | /* 156 | * Sets a cell value in the given board. 157 | */ 158 | void set_cell(struct board *b, int r, int c, int val) 159 | { 160 | assert_(b != NULL && 161 | r >= MIN_NUM && r <= MAX_NUM && 162 | c >= MIN_NUM && c <= MAX_NUM && 163 | val >= MIN_NUM && val <= MAX_NUM); 164 | 165 | assert_((! (*(b->cells[r][c].row_candidates))[val]) && 166 | (! (*(b->cells[r][c].col_candidates))[val]) && 167 | (! (*(b->cells[r][c].square_candidates))[val])); 168 | 169 | b->unset_cells -= 1; 170 | b->cells[r][c].has_value = 1; 171 | b->cells[r][c].value = val; 172 | use_candidate(b->cells[r][c].row_candidates, val); 173 | use_candidate(b->cells[r][c].col_candidates, val); 174 | use_candidate(b->cells[r][c].square_candidates, val); 175 | } 176 | 177 | /* 178 | * Unsets a cell value in the given board. 179 | */ 180 | void unset_cell(struct board *b, int r, int c, int val) 181 | { 182 | assert_(b != NULL && 183 | r >= MIN_NUM && r <= MAX_NUM && 184 | c >= MIN_NUM && c <= MAX_NUM && 185 | val >= MIN_NUM && val <= MAX_NUM); 186 | 187 | assert_((*(b->cells[r][c].row_candidates))[val] && 188 | (*(b->cells[r][c].col_candidates))[val] && 189 | (*(b->cells[r][c].square_candidates))[val]); 190 | 191 | b->unset_cells += 1; 192 | b->cells[r][c].has_value = 0; 193 | b->cells[r][c].value = 0; 194 | restore_candidate(b->cells[r][c].row_candidates, val); 195 | restore_candidate(b->cells[r][c].col_candidates, val); 196 | restore_candidate(b->cells[r][c].square_candidates, val); 197 | } 198 | 199 | /* 200 | * Checks if a cell value is set. Returns 1 if set, 0 otherwise. 201 | */ 202 | int is_set(struct board *b, int r, int c) 203 | { 204 | assert_(b != NULL && 205 | r >= MIN_NUM && r <= MAX_NUM && 206 | c >= MIN_NUM && c <= MAX_NUM); 207 | 208 | return (b->cells[r][c].has_value); 209 | } 210 | 211 | /* 212 | * Calculates the number following a given one circularly. 213 | */ 214 | int following(int num) 215 | { 216 | assert_(num >= MIN_NUM && num <= MAX_NUM); 217 | 218 | return ((num - MIN_NUM + 1) % TOTAL_NUMS + MIN_NUM); 219 | } 220 | 221 | /* 222 | * Calculates the cell following a given one. Advances from top to bottom and 223 | * left to right. Returns 0 if there is no next cell, 1 otherwise and modifies 224 | * the arguments to point to the next cell in that case. 225 | */ 226 | int next_cell(int *r, int *c) 227 | { 228 | assert_(r != NULL && c != NULL); 229 | 230 | if ((*r) == MAX_NUM && (*c) == MAX_NUM) 231 | return 0; 232 | 233 | *c = following(*c); 234 | if ((*c) == MIN_NUM) 235 | (*r) = following(*r); 236 | return 1; 237 | } 238 | 239 | /* 240 | * Prints the given board on screen. 241 | */ 242 | void print_board(struct board *b) 243 | { 244 | int i; 245 | int j; 246 | 247 | assert_(b != NULL); 248 | 249 | for (i = MIN_NUM; i <= MAX_NUM; ++i) { 250 | for (j = MIN_NUM; j <= MAX_NUM; ++j) 251 | printf(" %d", b->cells[i][j].value); 252 | printf("\n"); 253 | } 254 | } 255 | 256 | /* 257 | * Solves a board starting with the given cell. Returns 1 if the board could be 258 | * solved, 0 if not. 259 | */ 260 | int solve_board(struct board *b, int r, int c) 261 | { 262 | int prev; 263 | int val; 264 | 265 | assert_(b != NULL && 266 | r >= MIN_NUM && r <= MAX_NUM && 267 | c >= MIN_NUM && c <= MAX_NUM); 268 | 269 | /* Base case: board solved, print it. */ 270 | if (b->unset_cells == 0) { 271 | print_board(b); 272 | return 1; 273 | } 274 | 275 | /* Find the next unset cell. */ 276 | while (is_set(b, r, c) && next_cell(&r, &c)) 277 | ; 278 | 279 | /* This should never happen. */ 280 | if (is_set(b, r, c)) 281 | return 1; 282 | 283 | /* Try every possible cell value until the board can be solved. */ 284 | prev = MIN_NUM; 285 | while (1) { 286 | val = find_common_free(b->cells[r][c].row_candidates, 287 | b->cells[r][c].col_candidates, 288 | b->cells[r][c].square_candidates, 289 | prev); 290 | if (val == -1) 291 | break; 292 | 293 | set_cell(b, r, c, val); 294 | if (solve_board(b, r, c)) 295 | return 1; 296 | unset_cell(b, r, c, val); 297 | 298 | prev = val+1; 299 | } 300 | 301 | return 0; 302 | } 303 | 304 | /* 305 | * Reads a board from the given file. Format: a digit represents a cell value, 306 | * a dot represents an empty cell. Cells should be given from top to bottom and 307 | * left to right. All other characters are ignored. 308 | * 309 | * Example: 310 | * 311 | * 5 3 . . 7 . . . . 312 | * 6 . . 1 9 5 . . . 313 | * . 9 8 . . . . 6 . 314 | * 8 . . . 6 . . . 3 315 | * 4 . . 8 . 3 . . 1 316 | * 7 . . . 2 . . . 6 317 | * . 6 . . . . 2 8 . 318 | * . . . 4 1 9 . . 5 319 | * . . . . 8 . . 7 9 320 | * 321 | */ 322 | void read_board(FILE *f, struct board *b) 323 | { 324 | int row; 325 | int col; 326 | int c; 327 | 328 | assert_(f != NULL && b != NULL); 329 | 330 | row = MIN_NUM; 331 | col = MIN_NUM; 332 | 333 | while (! feof(f)) { 334 | c = fgetc(f); 335 | if ((isdigit(c) && c != '0') || c == '.') { 336 | if (c != '.') 337 | set_cell(b, row, col, (c - '0')); 338 | if (! next_cell(&row, &col)) 339 | break; 340 | } 341 | } 342 | } 343 | 344 | /* 345 | * 346 | * MAIN PROGRAM. 347 | * 348 | */ 349 | 350 | int main(int argc, char *argv[]) 351 | { 352 | FILE *in; 353 | struct board b; 354 | 355 | int ret; 356 | 357 | if (argc > 2) { 358 | fprintf(stderr, "ERROR: too many arguments\n"); 359 | return 1; 360 | } 361 | 362 | if (argc == 2) { 363 | in = fopen(argv[1], "r"); 364 | if (in == NULL) { 365 | fprintf(stderr, "ERROR: could not open \"%s\"\n", argv[1]); 366 | return 2; 367 | } 368 | } else { 369 | in = stdin; 370 | } 371 | 372 | /* Initialize data structures. */ 373 | init_board(&b); 374 | 375 | /* Read and solve board. */ 376 | read_board(in, &b); 377 | ret = solve_board(&b, MIN_NUM, MIN_NUM); 378 | 379 | /* Close input and return. */ 380 | fclose(in); 381 | 382 | if (! ret) 383 | fprintf(stderr, "ERROR: board could not be solved\n"); 384 | 385 | return (ret?0:3); 386 | } 387 | --------------------------------------------------------------------------------