-
Notifications
You must be signed in to change notification settings - Fork 1
/
sudoku.c
124 lines (104 loc) · 2.55 KB
/
sudoku.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>
#include <string.h>
void inputfill(int *sudoku) {
int row = 0;
while (row < 9) {
char buf[10];
printf("Row %d >>> ", row + 1);
fgets(buf, sizeof buf, stdin);
char *p;
if(p=strchr(buf, '\n')){ // check exist newline
*p = 0;
} else {
char c;
while ((c = getchar()) != EOF && c != '\n'); // clear upto newline
}
for (int i = 0; i < 9; i++) {
if ('0' > buf[i] || buf[i] > '9') {
row--;
printf("Bad input, enter 9x 0-9\n");
break;
}
sudoku[(row*9) + i] = buf[i] - 48;
}
row++;
}
printf("\n");
}
void display(int *sudoku) {
for (int i = 0; i < 81; i++) {
if (sudoku[i]) {
printf("%d ", sudoku[i]);
} else {
printf(". ");
}
if (i % 3 == 2) {
printf(" ");
}
if (i % 9 == 8) {
printf("\n");
if (i % 27 == 26) {
printf("\n");
}
}
}
}
int possible(int *sudoku, int pos) {
int bad = 0;
int c;
int startrow = (pos / 9) * 9; // checks rows
for (c = startrow; c < startrow+9; c++) {
bad |= 1 << sudoku[c];
}
int startcol = pos % 9; // checks columns
for (c = startcol; c < startcol+81; c+=9) {
bad |= 1 << sudoku[c];
}
int sboxc = (startcol / 3) * 3; // checks boxes
int sboxr = (startrow / 27) * 27;
for (int offset = 0; offset < 27; offset += 9) {
int grp = sboxc + sboxr + offset;
for (c = grp; c < grp+3; c++) {
bad |= 1 << sudoku[c];
}
}
return ~bad;
}
int solve(int *sudoku, int pos) {
int tries = possible(sudoku, pos);
int next = -1;
for (int c = pos+1; c < 81; c++) { // find the next blank
if (!sudoku[c]) {
next = c;
break;
}
}
for (int num = 1; num < 10; num++) {
if ((tries >> num) & 1) { // if the number can go here
sudoku[pos] = num;
if (next == -1) {
return 1;
}
if (solve(sudoku, next)) {
return 1;
}
}
}
sudoku[pos] = 0;
return 0;
}
int main() {
int sudoku[81];
inputfill(sudoku);
display(sudoku);
int fzero;
for (fzero = 0; fzero < 81; fzero++) {
if (!sudoku[fzero]) {
break;
}
}
solve(sudoku, fzero);
printf("\n\n");
display(sudoku);
return 0;
}