doasku

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

commit 63d9656c58864cb1199578a2fb9a443998a5a8e9
parent f8fc7a0c1b8f2edfdb7259eec445c4244dedcf5b
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Sat,  6 Apr 2024 21:19:35 +0200

Distinction between naked and hidden single

Diffstat:
Mmain.cpp | 63+++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 18 deletions(-)

diff --git a/main.cpp b/main.cpp @@ -65,12 +65,12 @@ class Ref { } } - changes_t get_lone() const { + changes_t get_hidden_singles() const { changes_t res; - for (uint8_t i = 0; i < 9; i++) { - if (std::popcount(ref[i]) != 1) continue; - res.emplace_back(std::countr_zero(ref[i]), i); + for (uint8_t candidate = 0; candidate < 9; candidate++) { + if (std::popcount(ref[candidate]) != 1) continue; + res.emplace_back(std::countr_zero(ref[candidate]), candidate); } return res; @@ -153,9 +153,25 @@ class Subgrid { ref.clear(rc, value); } - changes_t get_lone() const { + changes_t get_hidden_singles() const { if (is_finished()) return {}; - return ref.get_lone(); + return ref.get_hidden_singles(); + } + + changes_t get_naked_singles() const { + if (is_finished()) return {}; + + changes_t res; + + for (uint8_t i = 0; i < 9; i++) { + const auto values = get(i); + if (std::popcount(values) != 1) continue; + const auto value = std::countr_zero(values); + if (!ref.get(value)) continue; + res.emplace_back(i, value); + } + + return res; } std::array<changes_t, 2> check_ray() const { @@ -320,10 +336,10 @@ class Grid { uint8_t changes = 0; for (uint8_t subgrid = 0; subgrid < 9; subgrid++) { - const auto lones = subgrids[subgrid].get_lone(); - for (const auto [field, val] : lones) { + const auto hs = subgrids[subgrid].get_hidden_singles(); + for (const auto [field, val] : hs) { - std::cout << "lone: " << (int)subgrid << " " << (int)field << " " << int(val) + std::cout << "hidden singles: " << (int)subgrid << " " << (int)field << " " << int(val) << std::endl; set(subgrid, field, val); @@ -332,13 +348,13 @@ class Grid { } for (uint8_t row = 0; row < 9; row++) { - const auto lones = rows[row].get_lone(); - for (const auto [col, val] : lones) { + const auto hs = rows[row].get_hidden_singles(); + for (const auto [col, val] : hs) { const uint8_t subgrid = (row / 3) * 3 + col / 3; const uint8_t field = (row % 3) * 3 + col % 3; - std::cout << "lone row: " << (int)subgrid << " " << (int)field << " " << int(val) - << std::endl; + std::cout << "hidden singles row: " << (int)subgrid << " " << (int)field << " " + << int(val) << std::endl; set(subgrid, field, val); changes++; @@ -346,12 +362,23 @@ class Grid { } for (uint8_t col = 0; col < 9; col++) { - const auto lones = rows[col].get_lone(); - for (const auto [row, val] : lones) { + const auto hs = rows[col].get_hidden_singles(); + for (const auto [row, val] : hs) { const uint8_t subgrid = (col / 3) * 3 + row / 3; const uint8_t field = (col % 3) * 3 + row % 3; - std::cout << "lone col: " << (int)subgrid << " " << (int)field << " " << int(val) + std::cout << "hidden singles col: " << (int)subgrid << " " << (int)field << " " + << int(val) << std::endl; + + set(subgrid, field, val); + changes++; + } + } + + for (uint8_t subgrid = 0; subgrid < 9; subgrid++) { + const auto naked = subgrids[subgrid].get_naked_singles(); + for (const auto [field, val] : naked) { + std::cout << "naked singles: " << (int)subgrid << " " << (int)field << " " << int(val) << std::endl; set(subgrid, field, val); @@ -386,7 +413,7 @@ class Grid { _clear_col(mapping[i][0], col, val); _clear_col(mapping[i][1], col, val); - std::cout << "col: " << (int)i << " " << (int)col << " " << (int)val << std::endl; + std::cout << "ray col: " << (int)i << " " << (int)col << " " << (int)val << std::endl; changes++; } @@ -396,7 +423,7 @@ class Grid { _clear_row(mapping[i][0], row, val); _clear_row(mapping[i][1], row, val); - std::cout << "row: " << (int)i << " " << (int)row << " " << (int)val << std::endl; + std::cout << "ray row: " << (int)i << " " << (int)row << " " << (int)val << std::endl; changes++; } }