First pass at a sudoku solver: Puzzle Import
Imports a puzzle from a string and displays the restricted puzzle.
This commit is contained in:
commit
bcc5b5097e
8 changed files with 179 additions and 0 deletions
88
solver/puzzle.cpp
Normal file
88
solver/puzzle.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include "puzzle.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
uint8_t RowStart(uint8_t id) { return (id / 9) * 9; }
|
||||
uint8_t ColStart(uint8_t id) { return id % 9; }
|
||||
uint8_t BoxStart(uint8_t id) {
|
||||
uint8_t row = (RowStart(id) / 27) * 27;
|
||||
uint8_t col = (ColStart(id) / 3) * 3;
|
||||
return row + col;
|
||||
}
|
||||
|
||||
constexpr std::array<uint8_t, 9> kBoxOffsets{0, 1, 2, 9, 10, 11, 18, 19, 20};
|
||||
|
||||
} // namespace
|
||||
|
||||
Puzzle Puzzle::FromString(std::string puzzle) {
|
||||
assert(puzzle.length() == 81);
|
||||
Puzzle p;
|
||||
|
||||
for (int i = 0; i < 81; i++) {
|
||||
if (puzzle[i] == '.' || puzzle[i] == '0') {
|
||||
continue;
|
||||
}
|
||||
int diff = puzzle[i] - '0';
|
||||
if (diff < 1 || diff > 9) {
|
||||
assert(false && "Invalid input character");
|
||||
}
|
||||
p.AssignSquare(i, diff);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
std::string Puzzle::CurrentState() {
|
||||
std::ostringstream str;
|
||||
for (const Cell& c : cells_) {
|
||||
if (c.IsSolved()) {
|
||||
str << (int)c.value();
|
||||
} else {
|
||||
str << '.';
|
||||
}
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
std::string Puzzle::PencilMarkState() {
|
||||
std::ostringstream str;
|
||||
for (const Cell& c : cells_) {
|
||||
for (uint8_t i = 1; i <= 9; i++) {
|
||||
if (c.IsPossible(i)) {
|
||||
str << (int)i;
|
||||
}
|
||||
}
|
||||
str << ",";
|
||||
}
|
||||
// Erase the trailing ",".
|
||||
std::string temp = str.str();
|
||||
temp.erase(temp.end() - 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void Puzzle::AssignSquare(uint8_t id, uint8_t value) {
|
||||
assert(id < 81);
|
||||
assert(value >= 0 && value <= 9);
|
||||
|
||||
cells_[id] = Cell(value);
|
||||
|
||||
const uint8_t row = RowStart(id);
|
||||
for (uint8_t i = row; i < row + 9; i++) {
|
||||
cells_[i].Restrict(value);
|
||||
}
|
||||
|
||||
const uint8_t col = ColStart(id);
|
||||
for (uint8_t i = col; i < 81; i += 9) {
|
||||
cells_[i].Restrict(value);
|
||||
}
|
||||
|
||||
uint8_t box = BoxStart(id);
|
||||
for (uint8_t offset : kBoxOffsets) {
|
||||
cells_[box + offset].Restrict(value);
|
||||
}
|
||||
}
|
||||
|
||||
Puzzle::Puzzle() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue