diff --git a/036_valid_sudoku/Makefile b/036_valid_sudoku/Makefile new file mode 100644 index 0000000..fcc56aa --- /dev/null +++ b/036_valid_sudoku/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test valid_sudoku.c diff --git a/036_valid_sudoku/valid_sudoku.c b/036_valid_sudoku/valid_sudoku.c new file mode 100644 index 0000000..452fb2e --- /dev/null +++ b/036_valid_sudoku/valid_sudoku.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include + +struct stack { + int row; + int col; + int value; +}; + +static bool valid(char **board, int row, int col) +{ + int i, j, k; + char mark[10]; + + for (i = 0; i <= row; i++) { + memset(mark, 0, 10); + /* check row validity */ + for (j = 0; j < 9; j++) { + if (board[i][j] != '.') { + int index = board[i][j] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + } + } + + /* check column validity */ + for (i = 0; i <= col; i++) { + memset(mark, 0, 10); + for (j = 0; j < 9; j++) { + if (board[j][i] != '.') { + int index = board[j][i] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + } + } + + /* check sub-box validity */ + int count = row / 3 * 3 + col / 3 + 1; + for (k = 0; k < count; k++) { + int sr = k / 3 * 3; + int sc = (k % 3) * 3; + memset(mark, 0, 10); + for (i = sr; i < sr + 3; i++) { + for (j = sc; j < sc + 3; j++) { + if (board[i][j] != '.') { + int index = board[i][j] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + } + } + } + + return true; +} + +bool isValidSudoku(char** board, int boardRowSize, int boardColSize) { + if (boardRowSize != 9 || boardColSize != 9) { + return false; + } + + int i = 0, j = 0, k = 1, num = 0; + struct stack stack[81]; + + while (i < boardRowSize) { + if (board[i][j] == '.') { + while (k <= 9) { + board[i][j] = k + '0'; + if (valid(board, i, j)) { + stack[num].row = i; + stack[num].col = j; + stack[num].value = k; + num++; + k = 1; + break; + } + k++; + } + if (k == 10) { + if (num == 0) { + return false; + } + board[i][j] = '.'; + --num; + i = stack[num].row; + j = stack[num].col; + k = stack[num].value + 1; + board[i][j] = '.'; + continue; + } + } + /* next row */ + if (++j == boardColSize) { + j = 0; + i++; + } + } + + return true; +} + +int main(int argc, char **argv) +{ + int i, j; + char *str = argv[1]; + char **board = malloc(9 * sizeof(char *)); + for (i = 0; i < 9; i++) { + board[i] = malloc(10); + memcpy(board[i], str + i * 9, 9); + board[9] = '\0'; + char *row = board[i]; + for (j = 0; j < 9; j++) { + printf("%c ", row[j]); + } + printf("\n"); + } + printf("%s\n", isValidSudoku(board, 9, 9) ? "true" : "false"); + for (i = 0; i < 9; i++) { + char *row = board[i]; + for (j = 0; j < 9; j++) { + printf("%c ", row[j]); + } + printf("\n"); + } + return; +} diff --git a/037_sudoku_solver/Makefile b/037_sudoku_solver/Makefile new file mode 100644 index 0000000..debabd7 --- /dev/null +++ b/037_sudoku_solver/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test sudoku_solver.c diff --git a/037_sudoku_solver/sudoku_solver.c b/037_sudoku_solver/sudoku_solver.c new file mode 100644 index 0000000..30f699f --- /dev/null +++ b/037_sudoku_solver/sudoku_solver.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +struct stack { + int row; + int col; + int value; +}; + +static bool valid(char **board, int row, int col) +{ + int i, j, k; + char mark[10]; + + for (i = 0; i <= row; i++) { + memset(mark, 0, 10); + /* check row validity */ + for (j = 0; j < 9; j++) { + if (board[i][j] != '.') { + int index = board[i][j] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + } + } + + /* check column validity */ + for (i = 0; i <= col; i++) { + memset(mark, 0, 10); + for (j = 0; j < 9; j++) { + if (board[j][i] != '.') { + int index = board[j][i] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + } + } + + /* check sub-box validity */ + int count = row / 3 * 3 + col / 3 + 1; + for (k = 0; k < count; k++) { + int sr = k / 3 * 3; + int sc = (k % 3) * 3; + memset(mark, 0, 10); + for (i = sr; i < sr + 3; i++) { + for (j = sc; j < sc + 3; j++) { + if (board[i][j] != '.') { + int index = board[i][j] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + } + } + } + + return true; +} + +static void solveSudoku(char** board, int boardRowSize, int boardColSize) +{ + if (boardRowSize != 9 || boardColSize != 9) { + return; + } + + int i = 0, j = 0, k = 1, num = 0; + struct stack stack[81]; + + while (i < boardRowSize) { + if (board[i][j] == '.') { + while (k <= 9) { + board[i][j] = k + '0'; + if (valid(board, i, j)) { + stack[num].row = i; + stack[num].col = j; + stack[num].value = k; + num++; + k = 1; + break; + } + k++; + } + if (k == 10) { + if (num == 0) { + return; + } + board[i][j] = '.'; + --num; + i = stack[num].row; + j = stack[num].col; + k = stack[num].value + 1; + board[i][j] = '.'; + continue; + } + } + /* next row */ + if (++j == boardColSize) { + j = 0; + i++; + } + } +} + +int main(int argc, char **argv) +{ + int i, j; + char *str = argv[1]; + char **board = malloc(9 * sizeof(char *)); + for (i = 0; i < 9; i++) { + board[i] = malloc(10); + memcpy(board[i], str + i * 9, 9); + board[9] = '\0'; + char *row = board[i]; + for (j = 0; j < 9; j++) { + printf("%c ", row[j]); + } + printf("\n"); + } + solveSudoku(board, 9, 9); + for (i = 0; i < 9; i++) { + char *row = board[i]; + for (j = 0; j < 9; j++) { + printf("%c ", row[j]); + } + printf("\n"); + } + return; +}