FilesSubmittedBranchesLabelsClientsUsersJobsHelp
Tree viewShow file textShow revision historyShow/hide recent activityInformation
//depot/projects/sudoku/fast/sudoku.c#3

//depot/projects/sudoku/fast/sudoku.c#3 – integrate change 157 (text) ·revision history

1/*
2 * sudoku.c - backtracking sudoku solver
3 *
4 * Because everyone on the SkyTrain is doing these now and I refuse
5 * to do them by hand. -- ksimpson, may 2005
6 *
7 * fast branch: bitmasks instead of scanning. -- zz9
8 *
9 * usage: sudoku [puzzle.txt]
10 * puzzle is 9 lines of 9 chars, digits or '.' for blanks
11 */
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16static int grid[9][9];
17static long nodes = 0;
18
19static unsigned short rows[9], cols[9], boxes[9];
20
21#define BOX(r, c) (((r) / 3) * 3 + (c) / 3)
22
23static void place(int r, int c, int v)
24{
25 grid[r][c] = v;
26 rows[r] |= 1 << v;
27 cols[c] |= 1 << v;
28 boxes[BOX(r, c)] |= 1 << v;
29}
30
31static void unplace(int r, int c, int v)
32{
33 grid[r][c] = 0;
34 rows[r] &= ~(1 << v);
35 cols[c] &= ~(1 << v);
36 boxes[BOX(r, c)] &= ~(1 << v);
37}
38
39static int ok(int r, int c, int v)
40{
41 return !((rows[r] | cols[c] | boxes[BOX(r, c)]) & (1 << v));
42}
43
44static int solve(int pos)
45{
46 int r, c, v;
47
48 if (pos == 81)
49 return 1;
50 r = pos / 9;
51 c = pos % 9;
52 if (grid[r][c])
53 return solve(pos + 1);
54 for (v = 1; v <= 9; v++) {
55 nodes++;
56 if (ok(r, c, v)) {
57 place(r, c, v);
58 if (solve(pos + 1))
59 return 1;
60 unplace(r, c, v);
61 }
62 }
63 return 0;
64}
65
66static int read_grid(FILE *f)
67{
68 char line[64];
69 int r = 0, c;
70
71 while (r < 9 && fgets(line, sizeof line, f)) {
72 if (line[0] == '#' || line[0] == '\n')
73 continue;
74 /* anything that isn't 1-9 is a blank: '.', '0', '_', ' ' (job000005) */
75 for (c = 0; c < 9; c++)
76 grid[r][c] = (line[c] >= '1' && line[c] <= '9') ? line[c] - '0' : 0;
77 r++;
78 }
79 return r == 9;
80}
81
82static void print_grid(void)
83{
84 int r, c;
85
86 for (r = 0; r < 9; r++) {
87 for (c = 0; c < 9; c++) {
88 printf("%d", grid[r][c]);
89 if (c == 2 || c == 5)
90 printf(" | ");
91 }
92 printf("\n");
93 if (r == 2 || r == 5)
94 printf("----+-----+----\n");
95 }
96}
97
98int main(int argc, char **argv)
99{
100 FILE *f = stdin;
101 int i;
102
103 if (argc > 1 && !(f = fopen(argv[1], "r"))) {
104 perror(argv[1]);
105 return 1;
106 }
107 if (!read_grid(f)) {
108 fprintf(stderr, "sudoku: need 9 rows\n");
109 return 1;
110 }
111 for (i = 0; i < 81; i++) {
112 if (grid[i / 9][i % 9])
113 place(i / 9, i % 9, grid[i / 9][i % 9]);
114 }
115 if (!solve(0)) {
116 printf("no solution (are you sure you copied it right?)\n");
117 return 1;
118 }
119 print_grid();
120 fprintf(stderr, "%ld nodes\n", nodes);
121 return 0;
122}

P4Web/LINUX26X86/2005.1/82295 · Copyright © 1995-2005 Perforce Software · ttul.org