FilesSubmittedBranchesLabelsClientsUsersJobsHelp
Tree viewShow file textShow revision historyShow/hide recent activityInformation
Recent activity in //depot/projects/sudoku/fast/sudoku.c/...
2342005/11/02zz9fast: print solve time. 0.004s. ken's main branch: 0.31s. just saying.
1572005/06/02zz9integrate ken's blank-parsing fix from main into fast.
1502005/05/22zz9fast: bitmasks for row/col/box instead of scanning. fiendish 0.31s -> 0.04s on the G4.
1492005/05/21zz9branch sudoku main -> fast. going to make it go faster without breaking ken's version.
//depot/projects/sudoku/fast/sudoku.c#4

//depot/projects/sudoku/fast/sudoku.c#4 – edit change 234 (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#include <time.h>
16
17static int grid[9][9];
18static long nodes = 0;
19
20static unsigned short rows[9], cols[9], boxes[9];
21
22#define BOX(r, c) (((r) / 3) * 3 + (c) / 3)
23
24static void place(int r, int c, int v)
25{
26 grid[r][c] = v;
27 rows[r] |= 1 << v;
28 cols[c] |= 1 << v;
29 boxes[BOX(r, c)] |= 1 << v;
30}
31
32static void unplace(int r, int c, int v)
33{
34 grid[r][c] = 0;
35 rows[r] &= ~(1 << v);
36 cols[c] &= ~(1 << v);
37 boxes[BOX(r, c)] &= ~(1 << v);
38}
39
40static int ok(int r, int c, int v)
41{
42 return !((rows[r] | cols[c] | boxes[BOX(r, c)]) & (1 << v));
43}
44
45static int solve(int pos)
46{
47 int r, c, v;
48
49 if (pos == 81)
50 return 1;
51 r = pos / 9;
52 c = pos % 9;
53 if (grid[r][c])
54 return solve(pos + 1);
55 for (v = 1; v <= 9; v++) {
56 nodes++;
57 if (ok(r, c, v)) {
58 place(r, c, v);
59 if (solve(pos + 1))
60 return 1;
61 unplace(r, c, v);
62 }
63 }
64 return 0;
65}
66
67static int read_grid(FILE *f)
68{
69 char line[64];
70 int r = 0, c;
71
72 while (r < 9 && fgets(line, sizeof line, f)) {
73 if (line[0] == '#' || line[0] == '\n')
74 continue;
75 /* anything that isn't 1-9 is a blank: '.', '0', '_', ' ' (job000005) */
76 for (c = 0; c < 9; c++)
77 grid[r][c] = (line[c] >= '1' && line[c] <= '9') ? line[c] - '0' : 0;
78 r++;
79 }
80 return r == 9;
81}
82
83static void print_grid(void)
84{
85 int r, c;
86
87 for (r = 0; r < 9; r++) {
88 for (c = 0; c < 9; c++) {
89 printf("%d", grid[r][c]);
90 if (c == 2 || c == 5)
91 printf(" | ");
92 }
93 printf("\n");
94 if (r == 2 || r == 5)
95 printf("----+-----+----\n");
96 }
97}
98
99int main(int argc, char **argv)
100{
101 FILE *f = stdin;
102 int i;
103 clock_t t0;
104
105 if (argc > 1 && !(f = fopen(argv[1], "r"))) {
106 perror(argv[1]);
107 return 1;
108 }
109 if (!read_grid(f)) {
110 fprintf(stderr, "sudoku: need 9 rows\n");
111 return 1;
112 }
113 for (i = 0; i < 81; i++) {
114 if (grid[i / 9][i % 9])
115 place(i / 9, i % 9, grid[i / 9][i % 9]);
116 }
117 t0 = clock();
118 if (!solve(0)) {
119 printf("no solution (are you sure you copied it right?)\n");
120 return 1;
121 }
122 print_grid();
123 fprintf(stderr, "%ld nodes, %.3fs\n", nodes,
124 (double)(clock() - t0) / CLOCKS_PER_SEC);
125 return 0;
126}

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