Skip to content
This repository was archived by the owner on Aug 24, 2020. It is now read-only.

Commit 406ff40

Browse files
Merge pull request #9 from pieterbrandsen/optimize
Optimize
2 parents 33d8953 + 7c36e37 commit 406ff40

File tree

1 file changed

+92
-23
lines changed

1 file changed

+92
-23
lines changed

SudokuSolver/Logics/Solver.cs

+92-23
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,29 @@ public class Solver
1414
{
1515
private Random rnd = new Random();
1616

17+
/// <summary>
18+
/// return all candidates in the block containing the current cell
19+
/// </summary>
20+
/// <param name="row">the row number of the current cell</param>
21+
/// <param name="col">the column number of the current cell</param>
22+
/// <param name="candidates">list of possibly previously calculated cells</param>
23+
/// <param name="sudoku">reference of the sudoku</param>
24+
/// <returns>the partially filled list of candidates</returns>
1725
public List<int> getBlockNumbers(double row, double col, ref List<int> candidates, ref int[][] sudoku)
1826
{
19-
//calculate start coordinates for
20-
double blockStartRow = row - (row % 3);
21-
double blockStartColumn = col - (col % 3);
27+
// calculate start coordinates for the block of the cell
28+
// when row = 5:
29+
// ┌─┐ = row % 3 = 2, so 5 - 2 = 3 and this is the start col index of the block
30+
// 0 1 2 3 4 5
31+
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢
32+
double blockStartCol = row - (row % 3);
33+
// same as the above but for row number
34+
double blockStartRow = col - (col % 3);
2235

23-
for (int r = (int)blockStartRow; r < blockStartRow + 3; r++)
36+
// iterate through all block cells from top left postion of the current block
37+
for (int r = (int)blockStartCol; r < blockStartCol + 3; r++)
2438
{
25-
for (int c = (int)blockStartColumn; c < blockStartColumn + 3; c++)
39+
for (int c = (int)blockStartRow; c < blockStartRow + 3; c++)
2640
{
2741
candidates.Remove(sudoku[r][c]);
2842
}
@@ -31,6 +45,13 @@ public List<int> getBlockNumbers(double row, double col, ref List<int> candidate
3145
return candidates;
3246
}
3347

48+
/// <summary>
49+
/// return all candidates in the row containing the current cell
50+
/// </summary>
51+
/// <param name="row">the row number of the current cell</param>
52+
/// <param name="candidates">list of possibly previously calculated cells</param>
53+
/// <param name="sudoku">reference of the sudoku</param>
54+
/// <returns>the partially filled list of candidates</returns>
3455
public List<int> getRowNumbers(int row, ref List<int> candidates, ref int[][] sudoku)
3556
{
3657
for (int i = 0; i < 9; i++)
@@ -41,6 +62,13 @@ public List<int> getRowNumbers(int row, ref List<int> candidates, ref int[][] su
4162
return candidates;
4263
}
4364

65+
/// <summary>
66+
/// return all candidates in the column containing the current cell
67+
/// </summary>
68+
/// <param name="col">the column number of the current cell</param>
69+
/// <param name="candidates">list of possibly previously calculated cells</param>
70+
/// <param name="sudoku">reference of the sudoku</param>
71+
/// <returns>the partially filled list of candidates</returns>
4472
public List<int> getColumnNumbers(int col, ref List<int> candidates, ref int[][] sudoku)
4573
{
4674
for (int i = 0; i < 9; i++)
@@ -51,6 +79,13 @@ public List<int> getColumnNumbers(int col, ref List<int> candidates, ref int[][]
5179
return candidates;
5280
}
5381

82+
/// <summary>
83+
/// get all the candidates for the row, column and block containing the current cell
84+
/// </summary>
85+
/// <param name="row">the row number of the current cell</param>
86+
/// <param name="col">the column number of the current cell</param>
87+
/// <param name="sudoku">reference of the sudoku</param>
88+
/// <returns>the complete list of candidates</returns>
5489
public List<int> getAllCandidates(int row, int col, ref int[][] sudoku)
5590
{
5691
List<int> candidates = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
@@ -61,6 +96,13 @@ public List<int> getAllCandidates(int row, int col, ref int[][] sudoku)
6196
return candidates;
6297
}
6398

99+
/// <summary>
100+
/// Returns the sole candidate if there is only one
101+
/// </summary>
102+
/// <param name="row">the row number of the current cell</param>
103+
/// <param name="col">the column number of the current cell</param>
104+
/// <param name="sudoku">reference of the sudoku</param>
105+
/// <returns>the sole candidate value</returns>
64106
public int soleCandidate(int row, int col, ref int[][] sudoku)
65107
{
66108
//get all candidates for the current cell
@@ -74,7 +116,11 @@ public int soleCandidate(int row, int col, ref int[][] sudoku)
74116
return 0;
75117
}
76118

77-
119+
/// <summary>
120+
/// The method that solves the sudoku logically
121+
/// </summary>
122+
/// <param name="sudoku">reference of the sudoku</param>
123+
/// <returns>the solved sudoku</returns>
78124
public int[][] solveLogical(ref int[][] sudoku)
79125
{
80126
//check if there are cells solved and keep track of this using two variables
@@ -128,6 +174,13 @@ static int[][] CopyArrayBuiltIn(int[][] source)
128174
return dest;
129175
}
130176

177+
/// <summary>
178+
/// Recursive function based on guessing numbers picked from possible candidates
179+
/// </summary>
180+
/// <param name="row">the row number of the current cell</param>
181+
/// <param name="col">the column number of the current cell</param>
182+
/// <param name="sudoku">reference of the sudoku</param>
183+
/// <returns>false if the the call couldnt guess the right number. True if it can or the cell is already filled</returns>
131184
public bool SolveGuessingRecursion(int row, int col, ref int[][] sudoku)
132185
{
133186
//DateTime.Now;
@@ -158,8 +211,6 @@ public bool SolveGuessingRecursion(int row, int col, ref int[][] sudoku)
158211
//if there are candidates, walk through them in a linear fashion
159212
foreach (var guess in candidates)
160213
{
161-
//if (1 == random)
162-
// continue;
163214
//lets try out a guess from candidates
164215
sudoku[row][col] = guess;
165216

@@ -186,6 +237,12 @@ public bool SolveGuessingRecursion(int row, int col, ref int[][] sudoku)
186237
return false;
187238
}
188239

240+
/// <summary>
241+
/// Fills in an empty sudoku and then shuffles the rows and columns per block and also
242+
/// the block rows and columns themselves
243+
/// </summary>
244+
/// <param name="sudoku">the sudoku as reference</param>
245+
/// <returns>boolean succes</returns>
189246
public bool ShuffleSudoku (ref int[][] sudoku)
190247
{
191248
//fill all the cells
@@ -194,19 +251,20 @@ public bool ShuffleSudoku (ref int[][] sudoku)
194251
//keep track of random picks
195252
int rndInt = 0;
196253

197-
//
198-
// a column a block column
199-
// ┌─┐ ┌─────┐
200-
// ╔═╤═╤═╦═╤═╤═╦═╤═╤═╗ ┐
201-
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ │ a block row
202-
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ │
203-
// ╠═╪═╪═╬═╪═╪═╬═╪═╪═╣ ┘
204-
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ ┐ a row
205-
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ ┘
206-
// ╠═╪═╪═╬═╪═╪═╬═╪═╪═╣
207-
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢
208-
// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢
209-
// ╚═╧═╧═╩═╧═╧═╩═╧═╧═╝
254+
/// <example>
255+
/// a column a block column
256+
/// ┌─┐ ┌─────┐
257+
/// ╔═╤═╤═╦═╤═╤═╦═╤═╤═╗ ┐
258+
/// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ │ a block row
259+
/// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ │
260+
/// ╠═╪═╪═╬═╪═╪═╬═╪═╪═╣ ┘
261+
/// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ ┐ a row
262+
/// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢ ┘
263+
/// ╠═╪═╪═╬═╪═╪═╬═╪═╪═╣
264+
/// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢
265+
/// ╟─┼─┼─╫─┼─┼─╫─┼─┼─╢
266+
/// ╚═╧═╧═╩═╧═╧═╩═╧═╧═╝
267+
/// </example>
210268
//shuffle columns per block columns
211269
for (int i = 2; i >= 0; i--)
212270
{
@@ -278,6 +336,10 @@ public bool ShuffleSudoku (ref int[][] sudoku)
278336
return true;
279337
}
280338

339+
/// <summary>
340+
/// A list of shuffled indices later to be used for random deletion of cell values
341+
/// </summary>
342+
/// <returns>the shuffled list of random indices</returns>
281343
public List<int> createShuffledSudokuIndices()
282344
{
283345
//keep track of random picks;
@@ -323,19 +385,24 @@ public int[][] SolveGuessing(int[][] sudoku)
323385
return sudoku;
324386
}
325387

388+
// note the parameter with random object reference, this allows for different random numbers
389+
// through the entire program. The Random object is initialized in the view Sudoku.cshtml
326390
public int[][] CreateGuessing(int[][] sudoku, Random rnd)
327391
{
328392
ShuffleSudoku(ref sudoku);
329393

330-
//keep track of the cell coordinates we are going to zero in random order
394+
// the amount cells we want to keep
395+
int remainingCells = 13;
396+
397+
// keep track of the cell coordinates we are going to zero in random order
331398
// [0]{ 1 , 6 }
332399
// [1]{ 4 , 0 }
333400
// [2]{ 3 , 2 }
334401
// ...
335402
List<int> randomIndices = createShuffledSudokuIndices();
336403

337404
//walk trough all 81 (9*9) (shuffled) numbers to see wich cell can or cant be zeroed
338-
for (int i = 0; i < randomIndices.Count - 18; i++)
405+
for (int i = 0; i < randomIndices.Count - remainingCells; i++)
339406
{
340407
//cell number to coordinates
341408
int row = Convert.ToInt32(Math.Floor(Convert.ToDecimal(randomIndices[i] / 9)));
@@ -347,6 +414,8 @@ public int[][] CreateGuessing(int[][] sudoku, Random rnd)
347414
return sudoku;
348415
}
349416

417+
// note the parameter with random object reference, this allows for different random numbers
418+
// through the entire program. The Random object is initialized in the view Sudoku.cshtml
350419
public int[][] Create(int[][] sudoku, Random rnd)
351420
{
352421
ShuffleSudoku(ref sudoku);

0 commit comments

Comments
 (0)