Update Sudoku Solver to check for naked singles.
This commit is contained in:
parent
bcc5b5097e
commit
3dc9f04650
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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]; }
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue