Ok, so I looked into the stack overflow site and found some similar questions, but none of them seem to give me the solution to my problem here. If I am correct, arrays and objects are passed by reference automatically in JavaScript and TypeScript, so I can't seem to figure out why it is not working.
Here's my complete code: I am learning algorithms and data structures for my interviews
/**
* sudoku Problem Board
*/
let sudokuBoard: Array<Array<number>> = [
[0, 9, 5, 0, 0, 3, 0, 0, 2],
[0, 0, 0, 0, 0, 1, 0, 0, 0],
[6, 0, 2, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 7, 0, 0, 4, 0, 1],
[0, 0, 0, 0, 0, 0, 5, 0, 0],
[8, 0, 0, 0, 0, 0, 0, 3, 0],
[0, 0, 7, 1, 0, 0, 0, 5, 0],
[0, 1, 0, 8, 6, 0, 0, 2, 0],
[3, 0, 0, 0, 0, 4, 0, 0, 0],
];
/**
* Function to print the layout of sudoku board and its solution
*/
let printBoard = (sudokuBoard: Array<Array<number>>) => {
for (let i: number = 0; i < sudokuBoard.length; i++) {
if (i % 3 === 0 && i !== 0) {
console.log("-----------------------");
}
let output = ``;
for (let j: number = 0; j < sudokuBoard[0].length; j++) {
if (j % 3 === 0 && j !== 0) {
output += ` | `;
}
if (j === 8) {
output += `${sudokuBoard[i][j]}`;
} else {
output += `${sudokuBoard[i][j]} `;
}
}
console.log(output);
}
console.log("\n");
};
/**
* Find the empty cell within the board
* @param sudokuBoard board for which empty cell is to be found
*/
let findEmptyCell = (sudokuBoard: Array<Array<number>>): Array<number> => {
for (let i: number = 0; i < sudokuBoard.length; i++) {
for (let j: number = 0; j < sudokuBoard[0].length; j++) {
if (sudokuBoard[i][j] === 0) {
return [i, j];
}
}
}
return [-1, -1];
};
/**
* Main Function to call while passing the entire sudoku board to solve
* @param sudokuBoard
*/
let sudokuSolver = (sudokuBoard: Array<Array<number>>) => {
const emptyCellPos: Array<number> = findEmptyCell(sudokuBoard);
if (emptyCellPos[0] !== -1 && emptyCellPos[1] !== -1) {
const row: number = emptyCellPos[0];
const col: number = emptyCellPos[1];
solveCell(row, col, sudokuBoard);
}
};
/**
* Function to fill the values in the board
* @param row starting row index
* @param col starting col index
* @param sudokuBoard sudoku board to solve
*/
let solveCell = (
row: number,
col: number,
sudokuBoard: Array<Array<number>>
): boolean => {
let emptyEntry: number = 0; // value to fill when backtracking is done to restore the wrong cell with default value
/**
* Check if column and row bounds are intact and take actions accordingly
* When col bound is met, change the row
* When row bound is met, we have finished the board
*/
if (col === sudokuBoard[row].length) {
col = 0;
row++;
if (row === sudokuBoard.length) {
return true;
}
}
/**
* If number present already, recurse for next cell in the row
*/
if (sudokuBoard[row][col] !== emptyEntry) {
return solveCell(row, col + 1, sudokuBoard);
}
/**
* If empty cell is found, make a choice from decision set following the required constraint
* We loop from 1 to board length as all numbers that lie within, will be our decision space
* We then check each value whether it's suitable for that cell or not
* If yes, we place it in that cell and check the move for next cell, If it proceeds with true, we do nothing, otherwise we empty that cell with our default 'emptyEntry'
*/
for (let value: number = 1; value < sudokuBoard.length; value++) {
let placeValue: number = value;
if (placeCellValue(sudokuBoard, row, col, placeValue)) {
sudokuBoard[row][col] = value;
if (solveCell(row, col + 1, sudokuBoard)) {
return true;
}
sudokuBoard[row][col] = emptyEntry;
}
}
return false;
};
/**
* Check constraints for value before placing it in the given cell
* @param sudokuBoard sudoku board to solve
* @param row row index
* @param col col index
* @param placeValue value to place in the given sudokuboard[row][col] cell
*/
let placeCellValue = (
sudokuBoard: Array<Array<number>>,
row: number,
col: number,
placeValue: number
): boolean => {
/**
* Check for the row whether the value is already present
*/
for (let j: number = 0; j < sudokuBoard[0].length; j++) {
if (sudokuBoard[row][j] === placeValue) {
return false;
}
}
/**
* Check for the column whether the value is already present
*/
for (let i: number = 0; i < sudokuBoard.length; i++) {
if (sudokuBoard[i][col] === placeValue) {
return false;
}
}
/**
* Check if the value is present in the subgrid
*/
const regionSize = Math.sqrt(sudokuBoard.length);
const box_row = Math.floor(row / 3);
const box_col = Math.floor(col / 3);
const top_left_box_row = box_row * regionSize;
const top_left_box_col = box_col * regionSize;
for (let i: number = 0; i < regionSize; i++) {
for (let j: number = 0; j < regionSize; j++) {
if (
sudokuBoard[top_left_box_row + i][top_left_box_col + j] === placeValue
) {
return false;
}
}
}
return true;
};
console.log("\nSudoku Problem:\n");
printBoard(sudokuBoard);
sudokuSolver(sudokuBoard);
console.log("\nSudoku Solution:\n");
printBoard(sudokuBoard);
Both the printBoard method is printing the same thing. One more additional information, I am running this TS file using deno directly in the terminal. It compiles typescript automatically, which I find great for this task.
Any help will be appreciated. Thanks.