doasku

Human-like solver for sudoku
git clone git://git.dimitrijedobrota.com/doasku.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |

commit87ada69fe7c5f08b472fee90c45e0e5d17354f08
parente5cc8a937714a060616c910895c3b132cfe8ae15
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateWed, 3 Apr 2024 08:45:29 +0200

Read the grid from the command line and print it

Diffstat:
Mmain.cpp|+++++++++++++++++++++++++++++++++++++++++++--------------------------------

1 files changed, 43 insertions(+), 32 deletions(-)


diff --git a/main.cpp b/main.cpp

@@ -29,7 +29,7 @@ struct row_col_t {

struct row_col_rt {
row_col_rt(uint8_t row, uint8_t col) : row(row), col(col) {}
row_col_rt(uint8_t field) : row(2 - field % 3), col(field / 3) {}
explicit row_col_rt(uint8_t field) : row(2 - field % 3), col(field / 3) {}
row_col_rt(row_col_t rc);
friend std::ostream &operator<<(std::ostream &os, row_col_rt rc) {

@@ -50,24 +50,22 @@ class Row {

Row(uint64_t value = 0) : val(value) {}
operator uint64_t() const { return val; }
void set(uint8_t field, uint8_t value) { clear(field), toggle(field, value); }
void set_field(uint8_t field, uint8_t value) { clear(field), set(field, value); }
uint64_t get(uint8_t field) const { return (val >> 9 * field) & mask_field; }
uint64_t get(uint8_t field, uint8_t value) const { return (val >> 9 * field) & (1 << value); }
void set(uint8_t field) { val |= mask_field << 9 * field; }
void toggle(uint8_t field) { val ^= mask_field << 9 * field; }
void clear(uint8_t field) { val &= ~(mask_field << 9 * field); }
void set(uint8_t field, uint8_t value) { val |= 1ull << (9 * field + value); }
void toggle(uint8_t field, uint8_t value) { val ^= 1ull << (9 * field + value); }
void clear(uint8_t field, uint8_t value) { val &= ~(1ull << (9 * field + value)); }
void toggle_all(uint8_t value) { val ^= mask_value << value; }
void clear_all(uint8_t value) { val &= ~(mask_value << value); }
friend std::ostream &operator<<(std::ostream &os, const Row r) {
return os << std::setfill('0') << std::setw(14) << std::hex << (r.val & ((1ul << 54) - 1));
}
private:
uint64_t val;
};

@@ -79,6 +77,13 @@ class Subgrid {

uint64_t get(row_col_t rc) const { return rows[rc.row].get(rc.col); }
uint64_t get(row_col_rt rc) const { return rows[rc.row].get(rc.col + 3); }
uint8_t value(row_col_t rc) const {
if (!is_finished(rc)) return 0;
return 1 + std::countr_zero(get(rc));
}
bool is_finished(row_col_t rc) const { return finished & (1 << ::field(rc)); }
void set(uint8_t field, uint8_t value) {
assert(field < 9 && value < 9);

@@ -88,6 +93,8 @@ class Subgrid {

set(row_col_t(field), value);
set(row_col_rt(field), value);
finished |= 1 << field;
}
void clear_row(uint8_t row, uint8_t value) {

@@ -110,25 +117,41 @@ class Subgrid {

}
}
friend std::ostream &operator<<(std::ostream &os, const Subgrid &b) {
for (int i = 0; i < 3; i++) {
os << b.rows[i] << " ";
void check_lone() {
bool res = false;
for (int field = 0, mask = 1; field < 9; field++, mask++) {
if (finished & mask) continue;
if (std::popcount(get(field)) != 1) continue;
set(field, std::countr_zero(get(field)));
res = true;
}
return os;
}
void check_ray() {}
private:
void set(row_col_t rc, uint8_t value) { rows[rc.row].set(rc.col, value); }
void set(row_col_rt rcr, uint8_t value) { rows[rcr.row].set(rcr.col + 3, value); }
void set(row_col_t rc, uint8_t value) { rows[rc.row].set_field(rc.col, value); }
void set(row_col_rt rcr, uint8_t value) { rows[rcr.row].set_field(rcr.col + 3, value); }
void clear(row_col_t rc, uint8_t value) { rows[rc.row].clear(rc.col, value); }
void clear(row_col_rt rcr, uint8_t value) { rows[rcr.row].clear(rcr.col + 3, value); }
Row rows[3] = {~0, ~0, ~0};
uint16_t finished = 0;
};
class Grid {
public:
Grid(const std::string &s) {
int idx = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++, idx++) {
if (s[idx] == '0') continue;
set((i / 3) * 3 + j / 3, (i % 3) * 3 + j % 3, s[idx] - '1');
}
}
}
void set(uint8_t subgrid, uint8_t field, uint8_t value) {
assert(subgrid < 9 && field < 9 && value < 9);

@@ -161,16 +184,12 @@ class Grid {

if (i % 3 == 2) std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "Reversed Field: " << std::endl;
std::cout << "Board: " << std::endl;
for (uint8_t i = 0; i < 9; i++) {
for (uint8_t j = 0; j < 9; j++) {
const row_col_t subgrid = {uint8_t(i / 3), uint8_t(j / 3)};
const row_col_t field = {uint8_t(i % 3), uint8_t(j % 3)};
const row_col_rt rfield = row_col_rt(field);
std::bitset<9> value = subgrids[::field(subgrid)].get(rfield);
std::cout << value << " ";
std::cout << (int)subgrids[::field(subgrid)].value(field) << " ";
if (j % 3 == 2) std::cout << " ";
}
std::cout << std::endl;

@@ -178,25 +197,17 @@ class Grid {

}
}
friend std::ostream &operator<<(std::ostream &os, const Grid &g) {
for (int i = 0; i < 9; i++) {
std::cout << g.subgrids[i] << std::endl;
}
return os;
}
private:
Subgrid subgrids[9];
};
int main(void) {
Grid g;
int main(const int argc, const char *argv[]) {
g.set(0, 0, 3);
g.set(4, 4, 4);
g.set(8, 8, 0);
std::cout << g << std::endl;
g.print();
for (int i = 1; i < argc; i++) {
Grid g(argv[i]);
g.print();
}
return 0;
}