doasku

Sudoku solver
git clone git://git.dimitrijedobrota.com/doasku.git
Log | Files | Refs | README | LICENSE

commit 87ada69fe7c5f08b472fee90c45e0e5d17354f08
parent e5cc8a937714a060616c910895c3b132cfe8ae15
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Wed,  3 Apr 2024 10:45:29 +0200

Read the grid from the command line and print it

Diffstat:
Mmain.cpp | 75+++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file 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; }