Update Sudoku Solver to check for naked singles.

This commit is contained in:
Drew Galbraith 2023-04-17 16:48:38 -07:00
parent bcc5b5097e
commit 3dc9f04650
5 changed files with 40 additions and 0 deletions

View File

@ -6,6 +6,11 @@ int main(int argc, char** argv) {
Puzzle puzzle = Puzzle::FromString( Puzzle puzzle = Puzzle::FromString(
"3..4.162.1...8.4....5.2.83..578........7..5.3..29.4..748.53..1.2.3.9...." "3..4.162.1...8.4....5.2.83..578........7..5.3..29.4..748.53..1.2.3.9...."
".7...6.9."); ".7...6.9.");
while (puzzle.ApplyNextStep())
;
if (!puzzle.IsSolved()) {
std::cout << "Error! Couldn't Solve" << std::endl;
}
std::cout << "https://tiramisu.one/sudoku.html?p=" << puzzle.CurrentState() std::cout << "https://tiramisu.one/sudoku.html?p=" << puzzle.CurrentState()
<< "&m=" << puzzle.PencilMarkState() << std::endl; << "&m=" << puzzle.PencilMarkState() << std::endl;
} }

View File

@ -1,5 +1,6 @@
#include "cell.h" #include "cell.h"
#include <algorithm>
#include <cassert> #include <cassert>
Cell::Cell() Cell::Cell()
@ -15,3 +16,7 @@ void Cell::Restrict(uint8_t value) {
assert(value >= 1 && value <= 9); assert(value >= 1 && value <= 9);
possibilities_[value - 1] = false; possibilities_[value - 1] = false;
} }
uint8_t Cell::NumPossibilities() {
return std::count(possibilities_.begin(), possibilities_.end(), true);
}

View File

@ -15,6 +15,8 @@ class Cell {
void Restrict(uint8_t value); void Restrict(uint8_t value);
uint8_t NumPossibilities();
bool IsSolved() const { return state_ == Solved; } bool IsSolved() const { return state_ == Solved; }
uint8_t value() const { return value_; } uint8_t value() const { return value_; }
bool IsPossible(uint8_t v) const { return possibilities_[v - 1]; } bool IsPossible(uint8_t v) const { return possibilities_[v - 1]; }

View File

@ -1,5 +1,6 @@
#include "puzzle.h" #include "puzzle.h"
#include <algorithm>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -63,6 +64,30 @@ std::string Puzzle::PencilMarkState() {
return temp; return temp;
} }
bool Puzzle::IsSolved() {
return std::all_of(cells_.begin(), cells_.end(),
[](const Cell& c) { return c.IsSolved(); });
}
bool Puzzle::ApplyNextStep() {
// Search for a naked single.
for (int i = 0; i < 81; i++) {
if (cells_[i].IsSolved()) {
continue;
}
if (cells_[i].NumPossibilities() == 1) {
for (uint8_t v = 1; v <= 9; v++) {
if (cells_[i].IsPossible(v)) {
AssignSquare(i, v);
}
}
return true;
}
}
return false;
}
void Puzzle::AssignSquare(uint8_t id, uint8_t value) { void Puzzle::AssignSquare(uint8_t id, uint8_t value) {
assert(id < 81); assert(id < 81);
assert(value >= 0 && value <= 9); assert(value >= 0 && value <= 9);

View File

@ -12,6 +12,9 @@ class Puzzle {
std::string CurrentState(); std::string CurrentState();
std::string PencilMarkState(); std::string PencilMarkState();
bool IsSolved();
bool ApplyNextStep();
void AssignSquare(uint8_t id, uint8_t value); void AssignSquare(uint8_t id, uint8_t value);
private: private: