89 lines
1.8 KiB
C++
89 lines
1.8 KiB
C++
#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() {}
|