Skip to content

Commit 8f0ad95

Browse files
committed
Renamed 'LockedCandidates' to 'LockedCandidatesPointing' and added additional tests for the strategy.
1 parent d097f3c commit 8f0ad95

File tree

6 files changed

+181
-73
lines changed

6 files changed

+181
-73
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Repository contains tests for the library and a UI which uses the library and ca
1919
Out of the well known [Sudoku Solving Techniques](https://sudoku9x9.com/sudoku_solving_techniques_9x9.html), the solver currently implements:
2020
* Hidden Single
2121
* Naked Single
22-
* Locked Candidates
22+
* Locked Candidates (Pointing)
2323
* Naked Pair
2424
* Naked Triple
2525
* Naked Quad
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
using NUnit.Framework;
2+
using SimpleSudokuSolver.Model;
3+
using SimpleSudokuSolver.Strategy;
4+
5+
namespace SimpleSudokuSolver.Tests.Strategy
6+
{
7+
public class LockedCandidatesPointingTests : BaseStrategyTest
8+
{
9+
private readonly ISudokuSolverStrategy _strategy = new LockedCandidatesPointing();
10+
11+
[Test]
12+
public void LockedCandidatesPointingInColumnTest()
13+
{
14+
var sudoku = new int[,]
15+
{
16+
// From: https://sudoku9x9.com/locked_candidates.html
17+
{ 0,1,2,0,0,0,0,0,0 },
18+
{ 0,0,0,0,0,3,0,0,0 },
19+
{ 0,5,6,0,0,0,0,0,0 },
20+
{ 0,0,0,0,0,0,0,0,0 },
21+
{ 0,0,0,0,0,0,0,0,0 },
22+
{ 0,0,0,0,0,0,0,0,0 },
23+
{ 0,0,0,0,0,0,0,0,0 },
24+
{ 0,0,0,0,0,0,0,0,0 },
25+
{ 0,0,0,0,0,0,0,0,0 }
26+
};
27+
28+
var sudokuPuzzle = new SudokuPuzzle(sudoku);
29+
SolveUsingStrategy(sudokuPuzzle, _strategy);
30+
31+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[3, 0].CanBe, 3);
32+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 0].CanBe, 3);
33+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[5, 0].CanBe, 3);
34+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 0].CanBe, 3);
35+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 0].CanBe, 3);
36+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[8, 0].CanBe, 3);
37+
}
38+
39+
[Test]
40+
public void LockedCandidatesPointingInRowTest()
41+
{
42+
// From: https://sudoku9x9.com/locked_candidates.html, transposed
43+
var sudoku = new int[,]
44+
{
45+
{ 0,0,0,0,0,0,0,0,0 },
46+
{ 1,0,5,0,0,0,0,0,0 },
47+
{ 2,0,6,0,0,0,0,0,0 },
48+
{ 0,0,0,0,0,0,0,0,0 },
49+
{ 0,0,0,0,0,0,0,0,0 },
50+
{ 0,3,0,0,0,0,0,0,0 },
51+
{ 0,0,0,0,0,0,0,0,0 },
52+
{ 0,0,0,0,0,0,0,0,0 },
53+
{ 0,0,0,0,0,0,0,0,0 }
54+
};
55+
56+
var sudokuPuzzle = new SudokuPuzzle(sudoku);
57+
SolveUsingStrategy(sudokuPuzzle, _strategy);
58+
59+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 3].CanBe, 3);
60+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 4].CanBe, 3);
61+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 5].CanBe, 3);
62+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 6].CanBe, 3);
63+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 3);
64+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 8].CanBe, 3);
65+
}
66+
67+
[Test]
68+
public void LockedCandidatesPointingTest1()
69+
{
70+
var sudoku = new int[,]
71+
{
72+
// From: http://www.sudokuwiki.org/Intersection_Removal
73+
{ 0,1,7,9,0,3,6,0,0 },
74+
{ 0,0,0,0,8,0,0,0,0 },
75+
{ 9,0,0,0,0,0,5,0,7 },
76+
{ 0,7,2,0,1,0,4,3,0 },
77+
{ 0,0,0,4,0,2,0,7,0 },
78+
{ 0,6,4,3,7,0,2,5,0 },
79+
{ 7,0,1,0,0,0,0,6,5 },
80+
{ 0,0,0,0,3,0,0,0,0 },
81+
{ 0,0,5,6,0,1,7,2,0 }
82+
};
83+
84+
var sudokuPuzzle = new SudokuPuzzle(sudoku);
85+
86+
// must first use NakedQuad to eliminate some candidates
87+
SolveUsingStrategy(sudokuPuzzle, new NakedQuad());
88+
SolveUsingStrategy(sudokuPuzzle, _strategy);
89+
90+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 0].CanBe, 3);
91+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 1].CanBe, 3);
92+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 3);
93+
94+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 1].CanBe, 2);
95+
}
96+
97+
[Test]
98+
public void LockedCandidatesPointingTest2()
99+
{
100+
var sudoku = new int[,]
101+
{
102+
// From: http://www.sudokuwiki.org/Intersection_Removal
103+
{ 0,3,2,0,0,6,1,0,0 },
104+
{ 4,1,0,0,0,0,0,0,0 },
105+
{ 0,0,0,9,0,1,0,0,0 },
106+
{ 5,0,0,0,9,0,0,0,4 },
107+
{ 0,6,0,0,0,0,0,7,1 },
108+
{ 3,0,0,0,2,0,0,0,5 },
109+
{ 0,0,0,5,0,8,0,0,0 },
110+
{ 0,0,0,0,0,0,5,1,9 },
111+
{ 0,5,7,0,0,9,8,6,0 }
112+
};
113+
114+
var sudokuPuzzle = new SudokuPuzzle(sudoku);
115+
116+
// must first use HiddenPair to eliminate some candidates
117+
SolveUsingStrategy(sudokuPuzzle, new HiddenPair());
118+
SolveUsingStrategy(sudokuPuzzle, _strategy);
119+
120+
// In a row
121+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 6].CanBe, 2);
122+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 7].CanBe, 2);
123+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 8].CanBe, 2);
124+
125+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 1].CanBe, 4);
126+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 2].CanBe, 4);
127+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 4].CanBe, 4);
128+
129+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 4].CanBe, 7);
130+
131+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 3].CanBe, 4);
132+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 4].CanBe, 4);
133+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 5].CanBe, 4);
134+
135+
// In a column
136+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 1].CanBe, 7);
137+
138+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 2].CanBe, 1);
139+
140+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 5].CanBe, 7);
141+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 5].CanBe, 7);
142+
143+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 6].CanBe, 6);
144+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 6].CanBe, 6);
145+
146+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 8);
147+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 7].CanBe, 8);
148+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 7].CanBe, 8);
149+
}
150+
151+
[Test]
152+
public void LockedCandidatesPointingTest3()
153+
{
154+
var sudoku = new int[,]
155+
{
156+
// From: http://www.sudokuwiki.org/Intersection_Removal
157+
{ 9,3,0,0,5,0,0,0,0 },
158+
{ 2,0,0,6,3,0,0,9,5 },
159+
{ 8,5,6,0,0,2,0,0,0 },
160+
{ 0,0,3,1,8,0,5,7,0 },
161+
{ 0,0,5,0,2,0,9,8,0 },
162+
{ 0,8,0,0,0,5,0,0,0 },
163+
{ 0,0,0,8,0,0,1,5,9 },
164+
{ 5,0,8,2,1,0,0,0,4 },
165+
{ 0,0,0,5,6,0,0,0,8 }
166+
};
167+
168+
var sudokuPuzzle = new SudokuPuzzle(sudoku);
169+
SolveUsingStrategy(sudokuPuzzle, _strategy);
170+
171+
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 5].CanBe, 3);
172+
}
173+
}
174+
}

SimpleSudokuSolver.Tests/Strategy/LockedCandidatesTests.cs

Lines changed: 0 additions & 67 deletions
This file was deleted.

SimpleSudokuSolver.Tests/Strategy/NakedQuadTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void NakedQuadTest2()
4444
var sudoku = new int[,]
4545
{
4646
// From: http://www.manifestmaster.com/jetsudoku/nakedQuad.html
47-
// Naked quad in column - must first use LockedCandidates to eliminate some candidates
47+
// Naked quad in column - must first use LockedCandidatesPointing to eliminate some candidates
4848
{ 0,0,0,0,9,0,0,0,0 },
4949
{ 0,0,0,0,3,1,6,0,0 },
5050
{ 0,0,0,0,4,8,0,9,0 },
@@ -57,7 +57,7 @@ public void NakedQuadTest2()
5757
};
5858

5959
var sudokuPuzzle = new SudokuPuzzle(sudoku);
60-
SolveUsingStrategy(sudokuPuzzle, new LockedCandidates());
60+
SolveUsingStrategy(sudokuPuzzle, new LockedCandidatesPointing());
6161
SolveUsingStrategy(sudokuPuzzle, _strategy);
6262

6363
CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 2].CanBe, 3);

SimpleSudokuSolver/DefaultSolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public DefaultSolver(params ISudokuSolverStrategy[] strategies)
3333
new SingleInCells(),
3434
new HiddenSingle(),
3535
new NakedSingle(),
36-
new LockedCandidates(),
36+
new LockedCandidatesPointing(),
3737
new NakedPair(),
3838
new NakedTriple(),
3939
new NakedQuad(),

SimpleSudokuSolver/Strategy/LockedCandidates.cs renamed to SimpleSudokuSolver/Strategy/LockedCandidatesPointing.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ namespace SimpleSudokuSolver.Strategy
1212
/// <remarks>
1313
/// See also:
1414
/// - https://sudoku9x9.com/locked_candidates.html
15+
/// - http://www.sudokuwiki.org/Intersection_Removal (Pointing Pairs, Pointing Triples)
1516
/// </remarks>
16-
public class LockedCandidates : ISudokuSolverStrategy
17+
public class LockedCandidatesPointing : ISudokuSolverStrategy
1718
{
18-
public string StrategyName => "Locked Candidates";
19+
public string StrategyName => "Locked Candidates (Pointing)";
1920

2021
public SingleStepSolution SolveSingleStep(SudokuPuzzle sudokuPuzzle)
2122
{

0 commit comments

Comments
 (0)