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

//depot/projects/sudoku/fast/sudoku.c#2 – edit change 150 (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 for (c = 0; c < 9; c++)
75 grid[r][c] = (line[c] == '.') ? 0 : line[c] - '0';
76 r++;
77 }
78 return r == 9;
79}
80
81static void print_grid(void)
82{
83 int r, c;
84
85 for (r = 0; r < 9; r++) {
86 for (c = 0; c < 9; c++) {
87 printf("%d", grid[r][c]);
88 if (c == 2 || c == 5)
89 printf(" | ");
90 }
91 printf("\n");
92 if (r == 2 || r == 5)
93 printf("----+-----+----\n");
94 }
95}
96
97int main(int argc, char **argv)
98{
99 FILE *f = stdin;
100 int i;
101
102 if (argc > 1 && !(f = fopen(argv[1], "r"))) {
103 perror(argv[1]);
104 return 1;
105 }
106 if (!read_grid(f)) {
107 fprintf(stderr, "sudoku: need 9 rows\n");
108 return 1;
109 }
110 for (i = 0; i < 81; i++) {
111 if (grid[i / 9][i % 9])
112 place(i / 9, i % 9, grid[i / 9][i % 9]);
113 }
114 if (!solve(0)) {
115 printf("no solution (are you sure you copied it right?)\n");
116 return 1;
117 }
118 print_grid();
119 fprintf(stderr, "%ld nodes\n", nodes);
120 return 0;
121}

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