<p>Write a program to solve a Sudoku puzzle by filling the empty cells.</p>

<p>A sudoku solution must satisfy <strong>all of the following rules</strong>:</p>

<ol>
	<li>Each of the digits <code>1-9</code> must occur exactly once in each row.</li>
	<li>Each of the digits <code>1-9</code> must occur exactly once in each column.</li>
	<li>Each of the digits <code>1-9</code> must occur exactly once in each of the 9 <code>3x3</code> sub-boxes of the grid.</li>
</ol>

<p>The <code>&#39;.&#39;</code> character indicates empty cells.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Sudoku-by-L2G-20050714.svg/250px-Sudoku-by-L2G-20050714.svg.png" style="height:250px; width:250px" />
<pre>
<strong>Input:</strong> board = [[&quot;5&quot;,&quot;3&quot;,&quot;.&quot;,&quot;.&quot;,&quot;7&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;],[&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;1&quot;,&quot;9&quot;,&quot;5&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;],[&quot;.&quot;,&quot;9&quot;,&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;,&quot;.&quot;],[&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;3&quot;],[&quot;4&quot;,&quot;.&quot;,&quot;.&quot;,&quot;8&quot;,&quot;.&quot;,&quot;3&quot;,&quot;.&quot;,&quot;.&quot;,&quot;1&quot;],[&quot;7&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;2&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;6&quot;],[&quot;.&quot;,&quot;6&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;2&quot;,&quot;8&quot;,&quot;.&quot;],[&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;4&quot;,&quot;1&quot;,&quot;9&quot;,&quot;.&quot;,&quot;.&quot;,&quot;5&quot;],[&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;.&quot;,&quot;8&quot;,&quot;.&quot;,&quot;.&quot;,&quot;7&quot;,&quot;9&quot;]]
<strong>Output:</strong> [[&quot;5&quot;,&quot;3&quot;,&quot;4&quot;,&quot;6&quot;,&quot;7&quot;,&quot;8&quot;,&quot;9&quot;,&quot;1&quot;,&quot;2&quot;],[&quot;6&quot;,&quot;7&quot;,&quot;2&quot;,&quot;1&quot;,&quot;9&quot;,&quot;5&quot;,&quot;3&quot;,&quot;4&quot;,&quot;8&quot;],[&quot;1&quot;,&quot;9&quot;,&quot;8&quot;,&quot;3&quot;,&quot;4&quot;,&quot;2&quot;,&quot;5&quot;,&quot;6&quot;,&quot;7&quot;],[&quot;8&quot;,&quot;5&quot;,&quot;9&quot;,&quot;7&quot;,&quot;6&quot;,&quot;1&quot;,&quot;4&quot;,&quot;2&quot;,&quot;3&quot;],[&quot;4&quot;,&quot;2&quot;,&quot;6&quot;,&quot;8&quot;,&quot;5&quot;,&quot;3&quot;,&quot;7&quot;,&quot;9&quot;,&quot;1&quot;],[&quot;7&quot;,&quot;1&quot;,&quot;3&quot;,&quot;9&quot;,&quot;2&quot;,&quot;4&quot;,&quot;8&quot;,&quot;5&quot;,&quot;6&quot;],[&quot;9&quot;,&quot;6&quot;,&quot;1&quot;,&quot;5&quot;,&quot;3&quot;,&quot;7&quot;,&quot;2&quot;,&quot;8&quot;,&quot;4&quot;],[&quot;2&quot;,&quot;8&quot;,&quot;7&quot;,&quot;4&quot;,&quot;1&quot;,&quot;9&quot;,&quot;6&quot;,&quot;3&quot;,&quot;5&quot;],[&quot;3&quot;,&quot;4&quot;,&quot;5&quot;,&quot;2&quot;,&quot;8&quot;,&quot;6&quot;,&quot;1&quot;,&quot;7&quot;,&quot;9&quot;]]
<strong>Explanation:</strong>&nbsp;The input board is shown above and the only valid solution is shown below:

<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Sudoku-by-L2G-20050714_solution.svg/250px-Sudoku-by-L2G-20050714_solution.svg.png" style="height:250px; width:250px" />
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>board.length == 9</code></li>
	<li><code>board[i].length == 9</code></li>
	<li><code>board[i][j]</code> is a digit or <code>&#39;.&#39;</code>.</li>
	<li>It is <strong>guaranteed</strong> that the input board has only one solution.</li>
</ul>

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
            vector<vector<vector<int>>> boardVar(9, vector<vector<int> >(9, vector<int>(9)));
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j] == '.')
                boardVar[i][j] = { 1,2,3,4,5,6,7,8,9 };
            else
                boardVar[i][j] = { board[i][j] - '0'};
        }
        boardVar = RemoveVariant(boardVar);
    }

    boardVar = FindSolution(boardVar);

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            char c = boardVar[i][j][0] + '0';
            board[i][j] = c;
        }
    }

    }

    vector<int> RemoveValue(vector<int> vect, int value) {
    vect.erase(std::remove(vect.begin(), vect.end(), value), vect.end());
    return vect;
}

bool ContainValue(vector<int> array, int value) {
    for (int i = 0; i < array.size(); i++) {
        if (array[i] == value)
            return true;
    }
    return false;
}

bool ContainValue(vector<vector<int>> array, int value) {
    for (int i = 0; i < array.size(); i++) {
        if (array[i].size() == 1 && array[i][0] == value)
            return true;
    }
    return false;
}

vector<vector<int>> GetSquare(vector<vector<vector<int>>> board, int numRow, int numCol) {
    vector<vector<int>> result;
    int mod1 = numRow % 3;
    int mod2 = numCol % 3;
    int upLeftRow = 0;
    int upLeftCol = 0;

    if (mod1 == 0)
        upLeftRow = numRow;
    if (mod1 == 1)
        upLeftRow = numRow - 1;
    if (mod1 == 2)
        upLeftRow = numRow - 2;

    if (mod2 == 0)
        upLeftCol = numCol;
    if (mod2 == 1)
        upLeftCol = numCol - 1;
    if (mod2 == 2)
        upLeftCol = numCol - 2;

    for (int i = upLeftRow; i < upLeftRow + 3; i++) {
        for (int j = upLeftCol; j < upLeftCol + 3; j++) {
            vector<int> cell = { i,j };
            result.push_back(cell);
        }
    }
    return result;
}

bool RowCheck(vector<vector<vector<int>>>board) {
    for (int i = 0; i < 9; i++) {
        vector<int> nums = { 1,2,3,4,5,6,7,8,9 };
        for (int j = 0; j < 9; j++) {
            if (board[i][j].size() == 0)
                return false;
            if (board[i][j].size() > 1)
                continue;
            if (ContainValue(nums, board[i][j][0]))
                nums = RemoveValue(nums, board[i][j][0]);
            else
                return false;
        }
    }
    
    return true;
}

bool ColumnCheck(vector<vector<vector<int>>> board) {
    for (int i = 0; i < 9; i++) {
        vector<int> nums = { 1,2,3,4,5,6,7,8,9 };
        for (int j = 0; j < 9; j++) {
            if (board[j][i].size() == 0)
                return false;
            if (board[j][i].size() > 1)
                continue;
            if (ContainValue(nums, board[j][i][0]))
                nums = RemoveValue(nums, board[j][i][0]);
            else
                return false;
        }
    }

    return true;
}

bool SquareCheck(vector<vector<vector<int>>> board) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            vector<vector<int>> square = GetSquare(board, i * 3, j * 3);
            vector<int> nums = { 1,2,3,4,5,6,7,8,9 };
            for (int k = 0; k < square.size(); k++) {
                vector<int> cell = board[square[k][0]][square[k][1]];
                if (cell.size() == 0)
                    return false;
                if (cell.size() > 1)
                    continue;
                if (ContainValue(nums, cell[0]))
                    nums = RemoveValue(nums, cell[0]);
                else
                    return false;
            }
        }
    }
    return true;
}

vector<vector<vector<int>>> RemoveVariant(vector<vector<vector<int>>> board) {
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j].size() > 1)
                continue;
            int value = board[i][j][0];
            for (int k = 0; k < 9; k++) {
                if (board[i][k].size() > 1)
                    board[i][k]=RemoveValue(board[i][k], value);
            }
            for (int k = 0; k < 9; k++) {
                if (board[k][j].size() > 1)
                    board[k][j]=RemoveValue(board[k][j], value);
            }
            vector<vector<int>> square = GetSquare(board, i, j);
            for(vector<int> cell : square)
            {
                if (board[cell[0]][cell[1]].size() > 1)
                    board[cell[0]][cell[1]] = RemoveValue(board[cell[0]][cell[1]], value);
            }
        }
    }

    
    return board;
}

vector<vector<vector<int>>> RemoveVariantInRows(vector<vector<vector<int>>> board) {
    for (int num = 1; num < 10; num++) {
        for (int i = 0; i < 9; i++) {
            int numPos = 0;
            if (ContainValue(board[i], num))
                continue;
            for (int j = 0; j < 9; j++) {
                if (board[i][j].size() == 1)
                    continue;
                if (std::find(board[i][j].begin(), board[i][j].end(), num) != board[i][j].end())
                    numPos++;
            }
            if (numPos == 1) {
                int index = 0;
                while (index < 9) {
                    if (std::find(board[i][index].begin(), board[i][index].end(), num) != board[i][index].end())
                        break;
                    index++;
                }
                board[i][index] = { num };
            }
        }
    }
    return board;
}

vector<vector<vector<int>>> RemoveVariantInColumns(vector<vector<vector<int>>> board) {
    for (int num = 1; num < 10; num++) {
        for (int i = 0; i < 9; i++) {
            int numPos = 0;
            vector<vector<int>> column = { board[0][i],board[1][i],board[2][i],board[3][i], board[4][i],board[5][i], board[6][i],board[7][i], board[8][i] };
            if (ContainValue(column, num))
                continue;
            for (int j = 0; j < 9; j++) {
                if (board[j][i].size() == 1)
                    continue;
                if (std::find(board[j][i].begin(), board[j][i].end(), num) != board[j][i].end())
                    numPos++;
            }
            if (numPos == 1) {
                int index = 0;
                while (index < 9) {
                    if (std::find(board[index][i].begin(), board[index][i].end(), num) != board[index][i].end())
                        break;
                    index++;
                }
                board[index][i] = { num };
            }
        }
    }
    return board;
}

vector<vector<vector<int>>> RemoveVariantInSquare(vector<vector<vector<int>>> board) {
    for (int squareNumber = 0; squareNumber < 9; squareNumber++) {
        int numRow = squareNumber / 3;
        int numCol = squareNumber % 3;
        vector<vector<int>> square = GetSquare(board, numRow * 3, numCol * 3);
        for (int i = 0; i < 9; i++) {
            vector<int> cell = square[i];
            if (cell.size() == 1) {
                int value = cell[0];
                for (int j = 0; j < 9; j++) {
                    if (i == j)
                        continue;
                    square[j] = RemoveValue(square[j], value);
                }
            }
        }
    }
    return board;
}

int GetNumOfNotEmptyCells(vector<vector<vector<int>>> board) {
    int result = 0;
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j].size() == 1)
                result++;
        }
    }
    return result;
}

vector<vector<vector<int>>> FindSolution(vector<vector<vector<int>>> boardVar) {
    bool correct = RowCheck(boardVar) && ColumnCheck(boardVar) && SquareCheck(boardVar);
    int numOfNotEmptyCells = GetNumOfNotEmptyCells(boardVar);
    while (correct && numOfNotEmptyCells < 81)
    {
        boardVar = RemoveVariant(boardVar);
        boardVar = RemoveVariantInRows(boardVar);
        boardVar = RemoveVariantInColumns(boardVar);
        boardVar = RemoveVariantInSquare(boardVar);

        int newVal = GetNumOfNotEmptyCells(boardVar);
        if (newVal == numOfNotEmptyCells) {
            boardVar = AssumeOneValue(boardVar);
        }
        else {
            numOfNotEmptyCells = newVal;
        }

        correct = RowCheck(boardVar) && ColumnCheck(boardVar) && SquareCheck(boardVar);
    }
    if (correct && numOfNotEmptyCells == 81)
        return boardVar;
    else
        return {};
}

vector<vector<vector<int>>> AssumeOneValue(vector<vector<vector<int>>> board) {
    int minCountOfVars = 9;
    vector<int> rowColOfMin;
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j].size() < minCountOfVars && board[i][j].size()>1)
            {
                minCountOfVars = board[i][j].size();
                rowColOfMin = { i,j };
            }
        }
    }

    vector<vector<vector<int>>> newBoard = board;

    newBoard[rowColOfMin[0]][rowColOfMin[1]] = { newBoard[rowColOfMin[0]][rowColOfMin[1]][0] };


    newBoard = RemoveVariant(newBoard);
    newBoard = RemoveVariantInRows(newBoard);
    newBoard = RemoveVariantInColumns(newBoard);
    newBoard = RemoveVariantInSquare(newBoard);
    bool rowCheck = RowCheck(newBoard);
    bool colCheck = ColumnCheck(newBoard);
    bool squareCheck = SquareCheck(newBoard);
    bool isCorrect = rowCheck && colCheck && squareCheck;
    if (isCorrect) {
        vector<vector<vector<int>>> resultBoard = FindSolution(newBoard);
        if (resultBoard.size() == 0) {
            board[rowColOfMin[0]][rowColOfMin[1]] = RemoveValue(board[rowColOfMin[0]][rowColOfMin[1]], board[rowColOfMin[0]][rowColOfMin[1]][0]);
            return board;
        }
        return FindSolution(newBoard);
    }
    else
    {
        board[rowColOfMin[0]][rowColOfMin[1]] = RemoveValue(board[rowColOfMin[0]][rowColOfMin[1]], board[rowColOfMin[0]][rowColOfMin[1]][0]);
    }
    return board;
}


};
99690