#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>

void shuffleArray(int array[], int size) {
    for (int i = size - 1; i > 0; i--) {
        int j = rand() % (i + 1);
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}


void create(int board[9][9]){
    srand(time(NULL)); 
    int index = 0;
    for (int r = 0; r < 9; r+=3){
        int nums[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        shuffleArray(nums, 9);
        for (int i = r; i < r+3; i++) {
            for (int j = 0; j < 9; j += 3) {
                board[i][j] = nums[index++];
                if (index >= 9) {
                    index = 0;
            }
        }
    }
    }
    for(int j = 0;j < 9;j++){
       shuffleArray(board[j], 9);
    }
}


bool check(int matrix[9][9]) {

    for (int i = 0; i < 9; i++) {
        int count[10] = {0}; 
        for (int j = 0; j < 9; j++) {
            int num = matrix[i][j];
            if (num != 0) {
                count[num]++;
                if (count[num] > 1) {
                    printf("False: The number %d in the row %d has been used!\n", num, i + 1);
                    return false;
                }
            }
        }
    }


    for (int j = 0; j < 9; j++) {
        int count[10] = {0};
        for (int i = 0; i < 9; i++) {
            int num = matrix[i][j];
            if (num != 0) {
                count[num]++;
                if (count[num] > 1) {
                    printf("False: The number %d in the col %d has been used!\n", num, j + 1);
                    return false;
                }
            }
        }
    }

    for (int block = 0; block < 9; block++) {
        int count[10] = {0};
        int startRow = (block / 3) * 3;
        int startCol = (block % 3) * 3;
        for (int i = startRow; i < startRow + 3; i++) {
            for (int j = startCol; j < startCol + 3; j++) {
                int num = matrix[i][j];
                if (num != 0) {
                    count[num]++;
                    if (count[num] > 1) {
                        printf("False: The number %d in the block %d has been used!\n", num, block + 1);
                        return false;
                    }
                }
            }
        }
    }

    printf("True: Valid initial Sudoku matrix!\n");
  		return true;
}


bool complement(int board[9][9], int row, int col) {
    if (row == 9) {
        return true;
    }
    if (board[row][col] != 0) {
        if (col == 8) {
            return complement(board, row + 1, 0);
        } else {
            return complement(board, row, col + 1);
        }
    }
    for (int num = 1; num <= 9; num++) {
        bool valid = true;
        for (int i = 0; i < 9; i++) {
            
            if (board[row][i] == num || board[i][col] == num ||
                board[(row / 3) * 3 + i / 3][(col / 3) * 3 + i % 3] == num) {
                valid = false;
                break;
            }
        }
        if (valid) {
            board[row][col] = num;
            if (col == 8) {
                if (complement(board, row + 1, 0)) {
                    return true;
                }
            } else {
                if (complement(board, row, col + 1)) {
                    return true;
                }
            }
            board[row][col] = 0;
        }
    }
    return false;
}



void output(int board[9][9]){
    int i;
    for(i = 0;i < 9 ;i++){
        if(i %3 == 0){
            printf("|-----------------------|\n");
        }
        printf("| %d %d %d | %d %d %d | %d %d %d |\n",
        board[i][0],board[i][1],board[i][2],board[i][3],board[i][4],board[i][5],board[i][6],board[i][7],board[i][8]);
    }
    printf("|-----------------------|\n");
}




int main() {
    int board[9][9] = {0};
    create(board);
    printf("The original Sudoku matrix:\n");
    output(board);
    if (check(board)) {
        if (complement(board, 0, 0)) {
            printf("The solution of Sudoku matrix:\n");
            output(board);
        } else {
            printf("No solution!\n");
        }
    } else {
        printf("No solution!\n");
    }

    return 0;
}