Sudoku solver recursive solution with clear structure
up vote
4
down vote
favorite
Problem statement
Similar to Leetcode 37 Sudoku solver, the algorithm is to determine if the sudoku board can be filled with ‘1’,‘2’,…,‘9’.
A sudoku board is represented as a two-dimensional 9x9 array, each element is one of the characters ‘1’,‘2’,…,‘9’ or the '.' character. The dot character '.' stands for a blank space. The sudoku solver should fill the blank spaces with characters such that each row and each column and each 3 * 3 matrix forming 9 * 9 matrix have each character of '1', '2', ...,'9' exactly once.
In every row of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every column of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every 3x3 sub-board that is illustrated below, all characters ‘1’,‘2’,…,‘9’ appear exactly once.

My practice of algorithms
I practiced this algorithm through mock interview starting from this March 4 or 5 times. First time the peer complained to me that I do not know how to write a depth first search algorithm, I did not explicitly write down base case at the beginning of the function; Second time I was interrupted and told to write as simple solution as possible, specially showing that base case is to finish the depth first search and go to row 9 which is out of matrix. Do not write any double loops such as two nested for loops. And the code is much easy to read because the structure of depth first search is very clear. So I practiced a few times to write depth first search like the following, besides I started to read leetcode discussion panel for various solution.
Learning through mock interview
Sudoku solver algorithm is one of algorithms I have learned from various peers last 6 months. The peer with senior experience gave me feedback from low rate like "Do not know how to write code" since I did not write base case inside the function at the beginning, and then next practice I was coached by a younger peer to write depth first search from (0,0) and avoid any two for loops. After first two practices, I always like to write Sudoku solver using the following structure:
base case
depth first search
recursive function calls
back tracking if need
Algorithm analysis
I also like to share my algorithm of time complexity analysis. My analysis of the algorithm is that any element of matrix has at most 9 choice to fill from '1' to '9', and there is 81 elements in the matrix, so the time complexity can go up to 981 possibility, since the board already is filled with some elements, the backtrack and also early return, the time complexity can lower down, but the time complexity is unknown.
Favorite code review
One of my favorite review on Sudoku solver is solving Sudoku using backtracking. I try to use my question to help the review of the most popular algorithm as well. My review for the question is to use clear structure, explicitly write down base case using comment and also put base case in the first line of depth first search function, and start from (0,0) to do depth first search and use recursive function to help iterate the matrix, avoid double for loop. The structure is more simple without double for loop.
using System;
using System.Collections.Generic;
class Solution
{
public static bool SudokuSolve(char[,] board)
{
// your code goes here
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
return SudokuSolveHelper(board, 0, 0);
}
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
var visit = board[row, col];
var isDot = visit == '.';
var nextRow = col == 8 ? (row + 1) : row;
var nextCol = col == 8 ? 0 : (col + 1);
if (!isDot)
{
return SudokuSolveHelper(board, nextRow, nextCol);
}
// assume that it is digit number
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
{
board[row, col] = option;
var result = SudokuSolveHelper(board, nextRow, nextCol);
if (result)
{
return true;
}
board[row, col] = '.';
}
return false;
}
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
{
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
var available = new HashSet<char>(numbers);
// check by row
for (int col = 0; col < 9; col++)
{
var visit = board[currentRow, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by col
for (int row = 0; row < 9; row++)
{
var visit = board[row, currentCol];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by 3 * 3 matrix
var startRow = currentRow / 3 * 3;
var startCol = currentCol / 3 * 3;
for (int row = startRow; row < startRow + 3; row++)
{
for (int col = startCol; col < startCol + 3; col++)
{
var visit = board[row, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
}
return available;
}
static void Main(string args)
{
var board = new char[,]{
{'.','.','.','7','.','.','3','.','1'},
{'3','.','.','9','.','.','.','.','.'},
{'.','4','.','3','1','.','2','.','.'},
{'.','6','.','4','.','.','5','.','.'},
{'.','.','.','.','.','.','.','.','.'},
{'.','.','1','.','.','8','.','4','.'},
{'.','.','6','.','2','1','.','5','.'},
{'.','.','.','.','.','9','.','.','8'},
{'8','.','5','.','.','4','.','.','.'}};
Console.WriteLine(SudokuSolve(board));
}
}
c# algorithm interview-questions sudoku depth-first-search
add a comment |
up vote
4
down vote
favorite
Problem statement
Similar to Leetcode 37 Sudoku solver, the algorithm is to determine if the sudoku board can be filled with ‘1’,‘2’,…,‘9’.
A sudoku board is represented as a two-dimensional 9x9 array, each element is one of the characters ‘1’,‘2’,…,‘9’ or the '.' character. The dot character '.' stands for a blank space. The sudoku solver should fill the blank spaces with characters such that each row and each column and each 3 * 3 matrix forming 9 * 9 matrix have each character of '1', '2', ...,'9' exactly once.
In every row of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every column of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every 3x3 sub-board that is illustrated below, all characters ‘1’,‘2’,…,‘9’ appear exactly once.

My practice of algorithms
I practiced this algorithm through mock interview starting from this March 4 or 5 times. First time the peer complained to me that I do not know how to write a depth first search algorithm, I did not explicitly write down base case at the beginning of the function; Second time I was interrupted and told to write as simple solution as possible, specially showing that base case is to finish the depth first search and go to row 9 which is out of matrix. Do not write any double loops such as two nested for loops. And the code is much easy to read because the structure of depth first search is very clear. So I practiced a few times to write depth first search like the following, besides I started to read leetcode discussion panel for various solution.
Learning through mock interview
Sudoku solver algorithm is one of algorithms I have learned from various peers last 6 months. The peer with senior experience gave me feedback from low rate like "Do not know how to write code" since I did not write base case inside the function at the beginning, and then next practice I was coached by a younger peer to write depth first search from (0,0) and avoid any two for loops. After first two practices, I always like to write Sudoku solver using the following structure:
base case
depth first search
recursive function calls
back tracking if need
Algorithm analysis
I also like to share my algorithm of time complexity analysis. My analysis of the algorithm is that any element of matrix has at most 9 choice to fill from '1' to '9', and there is 81 elements in the matrix, so the time complexity can go up to 981 possibility, since the board already is filled with some elements, the backtrack and also early return, the time complexity can lower down, but the time complexity is unknown.
Favorite code review
One of my favorite review on Sudoku solver is solving Sudoku using backtracking. I try to use my question to help the review of the most popular algorithm as well. My review for the question is to use clear structure, explicitly write down base case using comment and also put base case in the first line of depth first search function, and start from (0,0) to do depth first search and use recursive function to help iterate the matrix, avoid double for loop. The structure is more simple without double for loop.
using System;
using System.Collections.Generic;
class Solution
{
public static bool SudokuSolve(char[,] board)
{
// your code goes here
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
return SudokuSolveHelper(board, 0, 0);
}
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
var visit = board[row, col];
var isDot = visit == '.';
var nextRow = col == 8 ? (row + 1) : row;
var nextCol = col == 8 ? 0 : (col + 1);
if (!isDot)
{
return SudokuSolveHelper(board, nextRow, nextCol);
}
// assume that it is digit number
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
{
board[row, col] = option;
var result = SudokuSolveHelper(board, nextRow, nextCol);
if (result)
{
return true;
}
board[row, col] = '.';
}
return false;
}
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
{
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
var available = new HashSet<char>(numbers);
// check by row
for (int col = 0; col < 9; col++)
{
var visit = board[currentRow, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by col
for (int row = 0; row < 9; row++)
{
var visit = board[row, currentCol];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by 3 * 3 matrix
var startRow = currentRow / 3 * 3;
var startCol = currentCol / 3 * 3;
for (int row = startRow; row < startRow + 3; row++)
{
for (int col = startCol; col < startCol + 3; col++)
{
var visit = board[row, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
}
return available;
}
static void Main(string args)
{
var board = new char[,]{
{'.','.','.','7','.','.','3','.','1'},
{'3','.','.','9','.','.','.','.','.'},
{'.','4','.','3','1','.','2','.','.'},
{'.','6','.','4','.','.','5','.','.'},
{'.','.','.','.','.','.','.','.','.'},
{'.','.','1','.','.','8','.','4','.'},
{'.','.','6','.','2','1','.','5','.'},
{'.','.','.','.','.','9','.','.','8'},
{'8','.','5','.','.','4','.','.','.'}};
Console.WriteLine(SudokuSolve(board));
}
}
c# algorithm interview-questions sudoku depth-first-search
I continue to learn the Sudoku solver algorithm last few months. I wrote the Sudoku solver algorithm in mock interview on March 14, 2018. I wrote the analysis, code and passed all test cases in 30 minutes. The code is integrated all code reviews from this post. Here is the code: gist.github.com/jianminchen/f1c8497ea3e4f53a850758295ae5f5d3
– Jianmin Chen
Mar 15 at 18:19
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
Problem statement
Similar to Leetcode 37 Sudoku solver, the algorithm is to determine if the sudoku board can be filled with ‘1’,‘2’,…,‘9’.
A sudoku board is represented as a two-dimensional 9x9 array, each element is one of the characters ‘1’,‘2’,…,‘9’ or the '.' character. The dot character '.' stands for a blank space. The sudoku solver should fill the blank spaces with characters such that each row and each column and each 3 * 3 matrix forming 9 * 9 matrix have each character of '1', '2', ...,'9' exactly once.
In every row of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every column of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every 3x3 sub-board that is illustrated below, all characters ‘1’,‘2’,…,‘9’ appear exactly once.

My practice of algorithms
I practiced this algorithm through mock interview starting from this March 4 or 5 times. First time the peer complained to me that I do not know how to write a depth first search algorithm, I did not explicitly write down base case at the beginning of the function; Second time I was interrupted and told to write as simple solution as possible, specially showing that base case is to finish the depth first search and go to row 9 which is out of matrix. Do not write any double loops such as two nested for loops. And the code is much easy to read because the structure of depth first search is very clear. So I practiced a few times to write depth first search like the following, besides I started to read leetcode discussion panel for various solution.
Learning through mock interview
Sudoku solver algorithm is one of algorithms I have learned from various peers last 6 months. The peer with senior experience gave me feedback from low rate like "Do not know how to write code" since I did not write base case inside the function at the beginning, and then next practice I was coached by a younger peer to write depth first search from (0,0) and avoid any two for loops. After first two practices, I always like to write Sudoku solver using the following structure:
base case
depth first search
recursive function calls
back tracking if need
Algorithm analysis
I also like to share my algorithm of time complexity analysis. My analysis of the algorithm is that any element of matrix has at most 9 choice to fill from '1' to '9', and there is 81 elements in the matrix, so the time complexity can go up to 981 possibility, since the board already is filled with some elements, the backtrack and also early return, the time complexity can lower down, but the time complexity is unknown.
Favorite code review
One of my favorite review on Sudoku solver is solving Sudoku using backtracking. I try to use my question to help the review of the most popular algorithm as well. My review for the question is to use clear structure, explicitly write down base case using comment and also put base case in the first line of depth first search function, and start from (0,0) to do depth first search and use recursive function to help iterate the matrix, avoid double for loop. The structure is more simple without double for loop.
using System;
using System.Collections.Generic;
class Solution
{
public static bool SudokuSolve(char[,] board)
{
// your code goes here
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
return SudokuSolveHelper(board, 0, 0);
}
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
var visit = board[row, col];
var isDot = visit == '.';
var nextRow = col == 8 ? (row + 1) : row;
var nextCol = col == 8 ? 0 : (col + 1);
if (!isDot)
{
return SudokuSolveHelper(board, nextRow, nextCol);
}
// assume that it is digit number
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
{
board[row, col] = option;
var result = SudokuSolveHelper(board, nextRow, nextCol);
if (result)
{
return true;
}
board[row, col] = '.';
}
return false;
}
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
{
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
var available = new HashSet<char>(numbers);
// check by row
for (int col = 0; col < 9; col++)
{
var visit = board[currentRow, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by col
for (int row = 0; row < 9; row++)
{
var visit = board[row, currentCol];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by 3 * 3 matrix
var startRow = currentRow / 3 * 3;
var startCol = currentCol / 3 * 3;
for (int row = startRow; row < startRow + 3; row++)
{
for (int col = startCol; col < startCol + 3; col++)
{
var visit = board[row, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
}
return available;
}
static void Main(string args)
{
var board = new char[,]{
{'.','.','.','7','.','.','3','.','1'},
{'3','.','.','9','.','.','.','.','.'},
{'.','4','.','3','1','.','2','.','.'},
{'.','6','.','4','.','.','5','.','.'},
{'.','.','.','.','.','.','.','.','.'},
{'.','.','1','.','.','8','.','4','.'},
{'.','.','6','.','2','1','.','5','.'},
{'.','.','.','.','.','9','.','.','8'},
{'8','.','5','.','.','4','.','.','.'}};
Console.WriteLine(SudokuSolve(board));
}
}
c# algorithm interview-questions sudoku depth-first-search
Problem statement
Similar to Leetcode 37 Sudoku solver, the algorithm is to determine if the sudoku board can be filled with ‘1’,‘2’,…,‘9’.
A sudoku board is represented as a two-dimensional 9x9 array, each element is one of the characters ‘1’,‘2’,…,‘9’ or the '.' character. The dot character '.' stands for a blank space. The sudoku solver should fill the blank spaces with characters such that each row and each column and each 3 * 3 matrix forming 9 * 9 matrix have each character of '1', '2', ...,'9' exactly once.
In every row of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every column of the array, all characters ‘1’,‘2’,…,‘9’ appear exactly once.
In every 3x3 sub-board that is illustrated below, all characters ‘1’,‘2’,…,‘9’ appear exactly once.

My practice of algorithms
I practiced this algorithm through mock interview starting from this March 4 or 5 times. First time the peer complained to me that I do not know how to write a depth first search algorithm, I did not explicitly write down base case at the beginning of the function; Second time I was interrupted and told to write as simple solution as possible, specially showing that base case is to finish the depth first search and go to row 9 which is out of matrix. Do not write any double loops such as two nested for loops. And the code is much easy to read because the structure of depth first search is very clear. So I practiced a few times to write depth first search like the following, besides I started to read leetcode discussion panel for various solution.
Learning through mock interview
Sudoku solver algorithm is one of algorithms I have learned from various peers last 6 months. The peer with senior experience gave me feedback from low rate like "Do not know how to write code" since I did not write base case inside the function at the beginning, and then next practice I was coached by a younger peer to write depth first search from (0,0) and avoid any two for loops. After first two practices, I always like to write Sudoku solver using the following structure:
base case
depth first search
recursive function calls
back tracking if need
Algorithm analysis
I also like to share my algorithm of time complexity analysis. My analysis of the algorithm is that any element of matrix has at most 9 choice to fill from '1' to '9', and there is 81 elements in the matrix, so the time complexity can go up to 981 possibility, since the board already is filled with some elements, the backtrack and also early return, the time complexity can lower down, but the time complexity is unknown.
Favorite code review
One of my favorite review on Sudoku solver is solving Sudoku using backtracking. I try to use my question to help the review of the most popular algorithm as well. My review for the question is to use clear structure, explicitly write down base case using comment and also put base case in the first line of depth first search function, and start from (0,0) to do depth first search and use recursive function to help iterate the matrix, avoid double for loop. The structure is more simple without double for loop.
using System;
using System.Collections.Generic;
class Solution
{
public static bool SudokuSolve(char[,] board)
{
// your code goes here
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
return SudokuSolveHelper(board, 0, 0);
}
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
var visit = board[row, col];
var isDot = visit == '.';
var nextRow = col == 8 ? (row + 1) : row;
var nextCol = col == 8 ? 0 : (col + 1);
if (!isDot)
{
return SudokuSolveHelper(board, nextRow, nextCol);
}
// assume that it is digit number
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
{
board[row, col] = option;
var result = SudokuSolveHelper(board, nextRow, nextCol);
if (result)
{
return true;
}
board[row, col] = '.';
}
return false;
}
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
{
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
var available = new HashSet<char>(numbers);
// check by row
for (int col = 0; col < 9; col++)
{
var visit = board[currentRow, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by col
for (int row = 0; row < 9; row++)
{
var visit = board[row, currentCol];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
// check by 3 * 3 matrix
var startRow = currentRow / 3 * 3;
var startCol = currentCol / 3 * 3;
for (int row = startRow; row < startRow + 3; row++)
{
for (int col = startCol; col < startCol + 3; col++)
{
var visit = board[row, col];
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
}
}
return available;
}
static void Main(string args)
{
var board = new char[,]{
{'.','.','.','7','.','.','3','.','1'},
{'3','.','.','9','.','.','.','.','.'},
{'.','4','.','3','1','.','2','.','.'},
{'.','6','.','4','.','.','5','.','.'},
{'.','.','.','.','.','.','.','.','.'},
{'.','.','1','.','.','8','.','4','.'},
{'.','.','6','.','2','1','.','5','.'},
{'.','.','.','.','.','9','.','.','8'},
{'8','.','5','.','.','4','.','.','.'}};
Console.WriteLine(SudokuSolve(board));
}
}
c# algorithm interview-questions sudoku depth-first-search
c# algorithm interview-questions sudoku depth-first-search
edited Nov 6 '17 at 18:55
asked Nov 6 '17 at 3:59
Jianmin Chen
1,1711727
1,1711727
I continue to learn the Sudoku solver algorithm last few months. I wrote the Sudoku solver algorithm in mock interview on March 14, 2018. I wrote the analysis, code and passed all test cases in 30 minutes. The code is integrated all code reviews from this post. Here is the code: gist.github.com/jianminchen/f1c8497ea3e4f53a850758295ae5f5d3
– Jianmin Chen
Mar 15 at 18:19
add a comment |
I continue to learn the Sudoku solver algorithm last few months. I wrote the Sudoku solver algorithm in mock interview on March 14, 2018. I wrote the analysis, code and passed all test cases in 30 minutes. The code is integrated all code reviews from this post. Here is the code: gist.github.com/jianminchen/f1c8497ea3e4f53a850758295ae5f5d3
– Jianmin Chen
Mar 15 at 18:19
I continue to learn the Sudoku solver algorithm last few months. I wrote the Sudoku solver algorithm in mock interview on March 14, 2018. I wrote the analysis, code and passed all test cases in 30 minutes. The code is integrated all code reviews from this post. Here is the code: gist.github.com/jianminchen/f1c8497ea3e4f53a850758295ae5f5d3
– Jianmin Chen
Mar 15 at 18:19
I continue to learn the Sudoku solver algorithm last few months. I wrote the Sudoku solver algorithm in mock interview on March 14, 2018. I wrote the analysis, code and passed all test cases in 30 minutes. The code is integrated all code reviews from this post. Here is the code: gist.github.com/jianminchen/f1c8497ea3e4f53a850758295ae5f5d3
– Jianmin Chen
Mar 15 at 18:19
add a comment |
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
The code looks reasonably clean and simple, but there are some minor things which in my opinion could be improved.
// your code goes here
This comment is a message to you about how to use the template which some system (Leetcode?) has given you. It's not a message to the maintenance programmer about your code, so you should delete it as soon as you've implemented that method.
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
Why return false and not throw new ArgumentException(nameof(board))? Well, ok, personally I'd split out ArgumentNullException and ArgumentOutOfRangeException cases, but the point is that these look like exception conditions rather than "no solution" conditions.
Why assume? Would it not make more sense to require that the board size be exactly 9 x 9?
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
I can figure out what's going on here based on the other code and the context provided in the question, but I think it would be worth a comment explaining why this is the base case, or a method-level doc comment explaining that the method searches in a given order (from which I can infer the base case).
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
availableNumbers is used once, so I personally would inline it. However, this is a matter of taste, and I wouldn't be surprised if someone else has previously given you the opposite feedback. What I can say is that the code is consistent about always pulling out these intermediate values, and consistency is good, so well done for that.
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
Why HashSet<Char>? Firstly, since nothing in the calling code cares about it being a HashSet<>, the principle of coding to the interface rather than the implementation says that this method should return an IEnumerable<>. Secondly, the use of Char rather than char is inconsistent with the method body. I personally prefer to use the keywords for those System. types which have them, but this is again a matter of taste.
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
There's nothing wrong with using char, but string is also an IEnumerable<char>, and it's less fiddly to type and to read var numbers = "123456789";.
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
This is a microoptimisation. I would be inclined to say that since we know that available doesn't contain '.' we can simplify to
available.Remove(visit);
and make it easier to see the method as a whole on screen.
Console.WriteLine(SudokuSolve(board));
Is there any reason for writing True rather than the actual solution?
Finally, a note on magic numbers. If I asked you to modify this to solve 16 x 16 Sudokus, how much would you need to change? How about 12 x 12 Sudokus, with the blocks being 3 x 4?
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
1
It seems to me that it would be more useful to print the 81 digits of the solution (board) rather than theboolreturn value ofSudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.
– Peter Taylor
Nov 7 '17 at 7:50
1
(1)Why assume?I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2)availableNumbers is used once, so I personally would inline itThe added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)
– Flater
Feb 2 at 15:36
|
show 1 more comment
up vote
0
down vote
I am not sure what the HashSet is doing for you. You add every digit to the HashSet and then remove what doesn't work. If you had a list and just added what worked that would be the same, right? Also the C++ code you pointed to has in the comments an efficient way to check row/column and box in a single loop as opposed to the 3 you have.
Finally, the guy who wrote "Do not know how to write code" probably had an inflated sense of how good he is. All code can be improved, but that is no reason to put people down.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f179725%2fsudoku-solver-recursive-solution-with-clear-structure%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
The code looks reasonably clean and simple, but there are some minor things which in my opinion could be improved.
// your code goes here
This comment is a message to you about how to use the template which some system (Leetcode?) has given you. It's not a message to the maintenance programmer about your code, so you should delete it as soon as you've implemented that method.
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
Why return false and not throw new ArgumentException(nameof(board))? Well, ok, personally I'd split out ArgumentNullException and ArgumentOutOfRangeException cases, but the point is that these look like exception conditions rather than "no solution" conditions.
Why assume? Would it not make more sense to require that the board size be exactly 9 x 9?
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
I can figure out what's going on here based on the other code and the context provided in the question, but I think it would be worth a comment explaining why this is the base case, or a method-level doc comment explaining that the method searches in a given order (from which I can infer the base case).
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
availableNumbers is used once, so I personally would inline it. However, this is a matter of taste, and I wouldn't be surprised if someone else has previously given you the opposite feedback. What I can say is that the code is consistent about always pulling out these intermediate values, and consistency is good, so well done for that.
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
Why HashSet<Char>? Firstly, since nothing in the calling code cares about it being a HashSet<>, the principle of coding to the interface rather than the implementation says that this method should return an IEnumerable<>. Secondly, the use of Char rather than char is inconsistent with the method body. I personally prefer to use the keywords for those System. types which have them, but this is again a matter of taste.
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
There's nothing wrong with using char, but string is also an IEnumerable<char>, and it's less fiddly to type and to read var numbers = "123456789";.
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
This is a microoptimisation. I would be inclined to say that since we know that available doesn't contain '.' we can simplify to
available.Remove(visit);
and make it easier to see the method as a whole on screen.
Console.WriteLine(SudokuSolve(board));
Is there any reason for writing True rather than the actual solution?
Finally, a note on magic numbers. If I asked you to modify this to solve 16 x 16 Sudokus, how much would you need to change? How about 12 x 12 Sudokus, with the blocks being 3 x 4?
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
1
It seems to me that it would be more useful to print the 81 digits of the solution (board) rather than theboolreturn value ofSudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.
– Peter Taylor
Nov 7 '17 at 7:50
1
(1)Why assume?I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2)availableNumbers is used once, so I personally would inline itThe added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)
– Flater
Feb 2 at 15:36
|
show 1 more comment
up vote
3
down vote
accepted
The code looks reasonably clean and simple, but there are some minor things which in my opinion could be improved.
// your code goes here
This comment is a message to you about how to use the template which some system (Leetcode?) has given you. It's not a message to the maintenance programmer about your code, so you should delete it as soon as you've implemented that method.
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
Why return false and not throw new ArgumentException(nameof(board))? Well, ok, personally I'd split out ArgumentNullException and ArgumentOutOfRangeException cases, but the point is that these look like exception conditions rather than "no solution" conditions.
Why assume? Would it not make more sense to require that the board size be exactly 9 x 9?
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
I can figure out what's going on here based on the other code and the context provided in the question, but I think it would be worth a comment explaining why this is the base case, or a method-level doc comment explaining that the method searches in a given order (from which I can infer the base case).
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
availableNumbers is used once, so I personally would inline it. However, this is a matter of taste, and I wouldn't be surprised if someone else has previously given you the opposite feedback. What I can say is that the code is consistent about always pulling out these intermediate values, and consistency is good, so well done for that.
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
Why HashSet<Char>? Firstly, since nothing in the calling code cares about it being a HashSet<>, the principle of coding to the interface rather than the implementation says that this method should return an IEnumerable<>. Secondly, the use of Char rather than char is inconsistent with the method body. I personally prefer to use the keywords for those System. types which have them, but this is again a matter of taste.
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
There's nothing wrong with using char, but string is also an IEnumerable<char>, and it's less fiddly to type and to read var numbers = "123456789";.
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
This is a microoptimisation. I would be inclined to say that since we know that available doesn't contain '.' we can simplify to
available.Remove(visit);
and make it easier to see the method as a whole on screen.
Console.WriteLine(SudokuSolve(board));
Is there any reason for writing True rather than the actual solution?
Finally, a note on magic numbers. If I asked you to modify this to solve 16 x 16 Sudokus, how much would you need to change? How about 12 x 12 Sudokus, with the blocks being 3 x 4?
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
1
It seems to me that it would be more useful to print the 81 digits of the solution (board) rather than theboolreturn value ofSudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.
– Peter Taylor
Nov 7 '17 at 7:50
1
(1)Why assume?I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2)availableNumbers is used once, so I personally would inline itThe added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)
– Flater
Feb 2 at 15:36
|
show 1 more comment
up vote
3
down vote
accepted
up vote
3
down vote
accepted
The code looks reasonably clean and simple, but there are some minor things which in my opinion could be improved.
// your code goes here
This comment is a message to you about how to use the template which some system (Leetcode?) has given you. It's not a message to the maintenance programmer about your code, so you should delete it as soon as you've implemented that method.
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
Why return false and not throw new ArgumentException(nameof(board))? Well, ok, personally I'd split out ArgumentNullException and ArgumentOutOfRangeException cases, but the point is that these look like exception conditions rather than "no solution" conditions.
Why assume? Would it not make more sense to require that the board size be exactly 9 x 9?
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
I can figure out what's going on here based on the other code and the context provided in the question, but I think it would be worth a comment explaining why this is the base case, or a method-level doc comment explaining that the method searches in a given order (from which I can infer the base case).
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
availableNumbers is used once, so I personally would inline it. However, this is a matter of taste, and I wouldn't be surprised if someone else has previously given you the opposite feedback. What I can say is that the code is consistent about always pulling out these intermediate values, and consistency is good, so well done for that.
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
Why HashSet<Char>? Firstly, since nothing in the calling code cares about it being a HashSet<>, the principle of coding to the interface rather than the implementation says that this method should return an IEnumerable<>. Secondly, the use of Char rather than char is inconsistent with the method body. I personally prefer to use the keywords for those System. types which have them, but this is again a matter of taste.
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
There's nothing wrong with using char, but string is also an IEnumerable<char>, and it's less fiddly to type and to read var numbers = "123456789";.
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
This is a microoptimisation. I would be inclined to say that since we know that available doesn't contain '.' we can simplify to
available.Remove(visit);
and make it easier to see the method as a whole on screen.
Console.WriteLine(SudokuSolve(board));
Is there any reason for writing True rather than the actual solution?
Finally, a note on magic numbers. If I asked you to modify this to solve 16 x 16 Sudokus, how much would you need to change? How about 12 x 12 Sudokus, with the blocks being 3 x 4?
The code looks reasonably clean and simple, but there are some minor things which in my opinion could be improved.
// your code goes here
This comment is a message to you about how to use the template which some system (Leetcode?) has given you. It's not a message to the maintenance programmer about your code, so you should delete it as soon as you've implemented that method.
if (board == null || board.GetLength(0) < 9 || board.GetLength(1) < 9)
{
return false;
}
// assume that 9 * 9
Why return false and not throw new ArgumentException(nameof(board))? Well, ok, personally I'd split out ArgumentNullException and ArgumentOutOfRangeException cases, but the point is that these look like exception conditions rather than "no solution" conditions.
Why assume? Would it not make more sense to require that the board size be exactly 9 x 9?
private static bool SudokuSolveHelper(char[,] board, int row, int col)
{
// base case
if (row > 8)
{
return true;
}
I can figure out what's going on here based on the other code and the context provided in the question, but I think it would be worth a comment explaining why this is the base case, or a method-level doc comment explaining that the method searches in a given order (from which I can infer the base case).
var availableNumbers = getAvailableNumbers(board, row, col);
foreach (var option in availableNumbers)
availableNumbers is used once, so I personally would inline it. However, this is a matter of taste, and I wouldn't be surprised if someone else has previously given you the opposite feedback. What I can say is that the code is consistent about always pulling out these intermediate values, and consistency is good, so well done for that.
private static HashSet<Char> getAvailableNumbers(char[,] board, int currentRow, int currentCol)
Why HashSet<Char>? Firstly, since nothing in the calling code cares about it being a HashSet<>, the principle of coding to the interface rather than the implementation says that this method should return an IEnumerable<>. Secondly, the use of Char rather than char is inconsistent with the method body. I personally prefer to use the keywords for those System. types which have them, but this is again a matter of taste.
var numbers = new char { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
There's nothing wrong with using char, but string is also an IEnumerable<char>, and it's less fiddly to type and to read var numbers = "123456789";.
var isDigit = visit != '.';
if (isDigit)
{
available.Remove(visit);
}
This is a microoptimisation. I would be inclined to say that since we know that available doesn't contain '.' we can simplify to
available.Remove(visit);
and make it easier to see the method as a whole on screen.
Console.WriteLine(SudokuSolve(board));
Is there any reason for writing True rather than the actual solution?
Finally, a note on magic numbers. If I asked you to modify this to solve 16 x 16 Sudokus, how much would you need to change? How about 12 x 12 Sudokus, with the blocks being 3 x 4?
answered Nov 6 '17 at 11:24
Peter Taylor
15.5k2658
15.5k2658
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
1
It seems to me that it would be more useful to print the 81 digits of the solution (board) rather than theboolreturn value ofSudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.
– Peter Taylor
Nov 7 '17 at 7:50
1
(1)Why assume?I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2)availableNumbers is used once, so I personally would inline itThe added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)
– Flater
Feb 2 at 15:36
|
show 1 more comment
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
1
It seems to me that it would be more useful to print the 81 digits of the solution (board) rather than theboolreturn value ofSudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.
– Peter Taylor
Nov 7 '17 at 7:50
1
(1)Why assume?I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2)availableNumbers is used once, so I personally would inline itThe added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)
– Flater
Feb 2 at 15:36
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
great code review. Here is my feedback, code to interface related to return function argument HashSet<int> is great teaching for me to learn as a concrete example, I give it 10 if I rate using 1 to 10. Write string "123456789" instead of using char array {'1', '2', '3', '4', '5', '6', '7', '8', '9'} , also my personal favorite advice. Based on IEnumerate<char> since in mock interview I only have 30 - 35 minutes, I am seeking ways to expedite the coding. Also I give it best rating on the advice.
– Jianmin Chen
Nov 6 '17 at 16:35
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I think that the comment to help explain base case should like "//Base case: if the row is incremented to 9 which is bigger than maximum row value of matrix 8, then all elements are filled with correct value.", good advice to remind me to work on an explanation.
– Jianmin Chen
Nov 6 '17 at 16:38
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
I like to give your feedback on pulling out intermediate variables. It is learning experience, I try to follow TED principle, E - express the intent, when I write code, I may have short memory and quickly forget what I like to express, so in mock interview/ Hackerrank contest, I prefer to write explicitly what I try to do, avoid giant expression, do one thing a time in one statement. I journal my practice and practice again until I can write and fit in 30 minutes with a working solution to pass all test cases for mock interview algorithm.
– Jianmin Chen
Nov 6 '17 at 19:37
1
1
It seems to me that it would be more useful to print the 81 digits of the solution (
board) rather than the bool return value of SudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.– Peter Taylor
Nov 7 '17 at 7:50
It seems to me that it would be more useful to print the 81 digits of the solution (
board) rather than the bool return value of SudokuSolve. If the reason is that that was the spec required by whoever set the question, then fair enough.– Peter Taylor
Nov 7 '17 at 7:50
1
1
(1)
Why assume? I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2) availableNumbers is used once, so I personally would inline it The added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)– Flater
Feb 2 at 15:36
(1)
Why assume? I have a feeling that the comment is part of a pseudo-code-comment that was there before the actual code. i.e. it means "from this point on, we can assume that the board is (at least) 9*9". OP may not care about larger boards since he is able to ignore additional rows and columns. (2) availableNumbers is used once, so I personally would inline it The added benefit of not inlining it is ease of debugging, it makes it easier to look up the value. Plus, the method seems complex enough that OP has tested its output plenty of times :)– Flater
Feb 2 at 15:36
|
show 1 more comment
up vote
0
down vote
I am not sure what the HashSet is doing for you. You add every digit to the HashSet and then remove what doesn't work. If you had a list and just added what worked that would be the same, right? Also the C++ code you pointed to has in the comments an efficient way to check row/column and box in a single loop as opposed to the 3 you have.
Finally, the guy who wrote "Do not know how to write code" probably had an inflated sense of how good he is. All code can be improved, but that is no reason to put people down.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
add a comment |
up vote
0
down vote
I am not sure what the HashSet is doing for you. You add every digit to the HashSet and then remove what doesn't work. If you had a list and just added what worked that would be the same, right? Also the C++ code you pointed to has in the comments an efficient way to check row/column and box in a single loop as opposed to the 3 you have.
Finally, the guy who wrote "Do not know how to write code" probably had an inflated sense of how good he is. All code can be improved, but that is no reason to put people down.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
add a comment |
up vote
0
down vote
up vote
0
down vote
I am not sure what the HashSet is doing for you. You add every digit to the HashSet and then remove what doesn't work. If you had a list and just added what worked that would be the same, right? Also the C++ code you pointed to has in the comments an efficient way to check row/column and box in a single loop as opposed to the 3 you have.
Finally, the guy who wrote "Do not know how to write code" probably had an inflated sense of how good he is. All code can be improved, but that is no reason to put people down.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I am not sure what the HashSet is doing for you. You add every digit to the HashSet and then remove what doesn't work. If you had a list and just added what worked that would be the same, right? Also the C++ code you pointed to has in the comments an efficient way to check row/column and box in a single loop as opposed to the 3 you have.
Finally, the guy who wrote "Do not know how to write code" probably had an inflated sense of how good he is. All code can be improved, but that is no reason to put people down.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
answered 2 hours ago
Guest
1
1
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Guest is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
add a comment |
2
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
2
2
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
Welcome to Code Review. Peter's answer already mentioned the HashSet ... beyond that there is really just the comment about all code can be improved... I am not sure this answer really provides much insightful about the code. Are there any other points you might mention?
– Sᴀᴍ Onᴇᴌᴀ
1 hour ago
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f179725%2fsudoku-solver-recursive-solution-with-clear-structure%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I continue to learn the Sudoku solver algorithm last few months. I wrote the Sudoku solver algorithm in mock interview on March 14, 2018. I wrote the analysis, code and passed all test cases in 30 minutes. The code is integrated all code reviews from this post. Here is the code: gist.github.com/jianminchen/f1c8497ea3e4f53a850758295ae5f5d3
– Jianmin Chen
Mar 15 at 18:19