From 0dd21db9075deaa5ac5c5346a42aa45449c2d147 Mon Sep 17 00:00:00 2001
From: IronicJuice <81492870+IronicJuice@users.noreply.github.com>
Date: Wed, 25 Sep 2024 17:21:17 +0200
Subject: [PATCH 1/5] Moved the succes condition for solveRec up before
skipping lowest candidates
---
SudoScript.Core/Solver.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/SudoScript.Core/Solver.cs b/SudoScript.Core/Solver.cs
index ffcccf0..d983c63 100644
--- a/SudoScript.Core/Solver.cs
+++ b/SudoScript.Core/Solver.cs
@@ -42,14 +42,14 @@ private static bool SolveRec(Board board, [NotNullWhen(true)] out Board? solvedB
orderedCells = orderedCells.SkipWhile(c => c.CandidateCount <= 1);
// The first cell contains the smallest amount of candidates.
int lowestCandidateCount = orderedCells.FirstOrDefault()?.CandidateCount ?? 1;
- // Take all cells with the least amount of candidates.
- orderedCells = orderedCells.TakeWhile(c => c.CandidateCount == lowestCandidateCount);
// If there are no cells with more than 1 candidate, the board is solved.
if (lowestCandidateCount == 1)
{
solvedBoard = board;
return true;
}
+ // Take all cells with the least amount of candidates.
+ orderedCells = orderedCells.TakeWhile(c => c.CandidateCount == lowestCandidateCount);
Cell cell = orderedCells.First();
foreach (int candidate in cell.Candidates())
From 4473955f65bd2c398323fe2b4b5752475d38392b Mon Sep 17 00:00:00 2001
From: IronicJuice <81492870+IronicJuice@users.noreply.github.com>
Date: Wed, 25 Sep 2024 18:17:53 +0200
Subject: [PATCH 2/5] Implemented IsSatisfactory. Changed the easy board in
SolverTests to also be satisfactory.
---
SudoScript.Core.Test/SolverTests.cs | 48 ++++++++++++++++++++++-------
SudoScript.Core/Solver.cs | 14 +++++++--
2 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/SudoScript.Core.Test/SolverTests.cs b/SudoScript.Core.Test/SolverTests.cs
index 5797310..a0281b4 100644
--- a/SudoScript.Core.Test/SolverTests.cs
+++ b/SudoScript.Core.Test/SolverTests.cs
@@ -6,17 +6,7 @@ namespace SudoScript.Core.Test;
internal sealed class SolverTests
{
- [Test()]
- public void CanSolveEmptySudoku()
- {
- Board board = Util.CreateStandardEmpty();
- Assert.DoesNotThrow(() => board = Solver.Solve(board));
- Assert.IsTrue(board.ValidateRules());
- Assert.IsFalse(board.Cells().Any(c => c.Digit == Cell.EmptyDigit));
- }
-
- [Test]
- public void CanSolveGeneratedSudoku()
+ public Board CreateEasyBoard()
{
Board board = Util.CreateStandardEmpty();
// Sudoku givens generated by https://sudoku.com/
@@ -39,6 +29,7 @@ public void CanSolveGeneratedSudoku()
board[8, 4].Digit = 8;
board[3, 5].Digit = 4;
+ board[4, 7].Digit = 2;
board[3, 6].Digit = 6;
board[5, 6].Digit = 7;
@@ -50,6 +41,7 @@ public void CanSolveGeneratedSudoku()
board[8, 7].Digit = 3;
board[9, 7].Digit = 5;
+ board[3, 9].Digit = 1;
board[2, 8].Digit = 9;
board[4, 8].Digit = 7;
board[5, 8].Digit = 4;
@@ -59,6 +51,23 @@ public void CanSolveGeneratedSudoku()
board[7, 9].Digit = 9;
board[8, 9].Digit = 7;
+ return board;
+ }
+
+ [Test()]
+ public void CanSolveEmptySudoku()
+ {
+ Board board = Util.CreateStandardEmpty();
+ Assert.DoesNotThrow(() => board = Solver.Solve(board));
+ Assert.IsTrue(board.ValidateRules());
+ Assert.IsFalse(board.Cells().Any(c => c.Digit == Cell.EmptyDigit));
+ }
+
+ [Test]
+ public void CanSolveGeneratedSudoku()
+ {
+ Board board = CreateEasyBoard();
+
Console.WriteLine(board.ToString());
Console.WriteLine("-------------------------------------------------");
@@ -68,4 +77,21 @@ public void CanSolveGeneratedSudoku()
Console.WriteLine(board.ToString());
}
+
+ [Test]
+ public void IsSatisfactoryTest()
+ {
+ Board board = CreateEasyBoard();
+
+ Assert.IsTrue(Solver.IsSatisfactory(board));
+ }
+
+ [Test]
+ public void IsNotSatisfactoryTest()
+ {
+ Board board = Util.CreateStandardEmpty();
+
+ Assert.IsFalse(Solver.IsSatisfactory(board));
+ }
+
}
diff --git a/SudoScript.Core/Solver.cs b/SudoScript.Core/Solver.cs
index d983c63..4695c82 100644
--- a/SudoScript.Core/Solver.cs
+++ b/SudoScript.Core/Solver.cs
@@ -76,9 +76,19 @@ public static Board GenerateSolveable(Board board)
throw new NotImplementedException();
}
- public static bool IsSatisfactory(Board board)
+ public static bool IsSatisfactory(Board board) // Certain methods for eliminating candidates using inference are not currently implemented. Implementing them would make this function more acurate.
{
- throw new NotImplementedException();
+ // Eliminate candidates from all rules untill nothing changes.
+ while (board.EliminateCandidates());
+ // If the board is solved, it does not require trial and error.
+ foreach (Cell cell in board.Cells())
+ {
+ if (cell.CandidateCount > 1)
+ {
+ return false;
+ }
+ }
+ return true;
}
public static bool IsProper(Board board)
From 3d0756ade2ef8d00fb940eb570e937b406a2d6df Mon Sep 17 00:00:00 2001
From: IronicJuice <81492870+IronicJuice@users.noreply.github.com>
Date: Wed, 25 Sep 2024 18:32:05 +0200
Subject: [PATCH 3/5] Added documentation for IsSatisfactory
---
SudoScript.Core/Solver.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/SudoScript.Core/Solver.cs b/SudoScript.Core/Solver.cs
index 4695c82..8ea9e47 100644
--- a/SudoScript.Core/Solver.cs
+++ b/SudoScript.Core/Solver.cs
@@ -76,6 +76,11 @@ public static Board GenerateSolveable(Board board)
throw new NotImplementedException();
}
+ ///
+ /// Checks if the board can be solved by just using the EliminateCandidates methods from units.
+ ///
+ ///
+ /// True if the board can be solved without trial and error guessing.
public static bool IsSatisfactory(Board board) // Certain methods for eliminating candidates using inference are not currently implemented. Implementing them would make this function more acurate.
{
// Eliminate candidates from all rules untill nothing changes.
From 2cdf711ba9ea9d7a939b0dd3d334d6620bca0734 Mon Sep 17 00:00:00 2001
From: IronicJuice <81492870+IronicJuice@users.noreply.github.com>
Date: Wed, 25 Sep 2024 18:34:57 +0200
Subject: [PATCH 4/5] changed the solve check to actually use the function from
Board
---
SudoScript.Core/Solver.cs | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/SudoScript.Core/Solver.cs b/SudoScript.Core/Solver.cs
index 8ea9e47..4b1fe80 100644
--- a/SudoScript.Core/Solver.cs
+++ b/SudoScript.Core/Solver.cs
@@ -86,14 +86,7 @@ public static Board GenerateSolveable(Board board)
// Eliminate candidates from all rules untill nothing changes.
while (board.EliminateCandidates());
// If the board is solved, it does not require trial and error.
- foreach (Cell cell in board.Cells())
- {
- if (cell.CandidateCount > 1)
- {
- return false;
- }
- }
- return true;
+ return board.IsSolved();
}
public static bool IsProper(Board board)
From 8ba8763dc7cb83b0430e1061a802ce90697232bc Mon Sep 17 00:00:00 2001
From: IronicJuice <81492870+IronicJuice@users.noreply.github.com>
Date: Wed, 25 Sep 2024 18:39:45 +0200
Subject: [PATCH 5/5] spelling error
---
SudoScript.Core/Solver.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SudoScript.Core/Solver.cs b/SudoScript.Core/Solver.cs
index 4b1fe80..4bc9726 100644
--- a/SudoScript.Core/Solver.cs
+++ b/SudoScript.Core/Solver.cs
@@ -20,7 +20,7 @@ public static Board Solve(Board board)
private static bool SolveRec(Board board, [NotNullWhen(true)] out Board? solvedBoard)
{
- // Eliminate candidates from all rules untill nothing changes.
+ // Eliminate candidates from all rules until nothing changes.
while (board.EliminateCandidates()) ;
// We hit an invalid state, and must backtrack.