commit a4a5210429ab211058108e0850c8f284d7a375bc
parent 55d045aeca3466f352cab5b9c6059c698dfba614
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Wed, 3 Apr 2024 21:34:50 +0200
Add reference counting to find loners in subgrid
Diffstat:
M | main.cpp | | | 66 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 66 insertions(+), 0 deletions(-)
diff --git a/main.cpp b/main.cpp
@@ -89,6 +89,8 @@ 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); }
+ uint16_t get_ref(row_col_t rc) const { return ref[::field(rc)]; }
+
uint8_t value(row_col_t rc) const {
if (!is_finished(rc)) return 0;
return 1 + std::countr_zero(get(rc));
@@ -107,7 +109,12 @@ class Subgrid {
set(row_col_t(field), value);
set(row_col_rt(field), value);
+ for (int i = 0; i < 9; i++) {
+ ref[i] &= ~(1 << field);
+ }
+
finished |= 1 << field;
+ ref[value] = 0;
}
void clear_row(uint8_t row, uint8_t value) {
@@ -115,6 +122,7 @@ class Subgrid {
for (uint8_t i = 0; i < 3; i++) {
const row_col_t rc = {row, i};
+ ref[value] &= ~(1 << ::field(rc));
clear(row_col_rt(rc), value);
clear(rc, value);
}
@@ -125,6 +133,7 @@ class Subgrid {
for (uint8_t i = 0; i < 3; i++) {
const row_col_t rc = {i, col};
+ ref[value] &= ~(1 << ::field(rc));
clear(row_col_rt(rc), value);
clear(rc, value);
}
@@ -142,6 +151,12 @@ class Subgrid {
if (std::popcount(get(field)) != 1) continue;
res.emplace_back(field, std::countr_zero(get(field)));
}
+
+ for (int i = 0; i < 9; i++) {
+ if (std::popcount(ref[i]) != 1) continue;
+ res.emplace_back(std::countr_zero(ref[i]), i);
+ }
+
return res;
}
@@ -229,6 +244,14 @@ class Subgrid {
mask(rc, value[field]);
res = true;
+
+ // remove cleared from reference
+ uint64_t tvalue = value[field];
+ while (tvalue) {
+ uint16_t idx = std::countr_zero(tvalue);
+ ref[idx] &= ~(1 << nfield);
+ tvalue ^= 1ull << idx;
+ }
}
}
}
@@ -237,6 +260,34 @@ class Subgrid {
return res;
}
+ friend std::ostream &operator<<(std::ostream &os, Subgrid s) {
+ os << std::endl << "Field:" << std::endl;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ std::cout << std::bitset<9>(s.get(row_col_t(i, j))) << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ os << std::endl << "Rev:" << std::endl;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ std::cout << std::bitset<9>(s.get(row_col_rt(i, j))) << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ os << std::endl << "Refs:" << std::endl;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ std::cout << std::bitset<9>(s.get_ref(row_col_t(i, j))) << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ return os;
+ }
+
private:
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); }
@@ -248,6 +299,8 @@ class Subgrid {
void mask(row_col_rt rcr, uint8_t value) { rows[rcr.row].mask(rcr.col + 3, value); }
Row rows[3] = {~0, ~0, ~0};
+ uint16_t ref[9] = {mask_field, mask_field, mask_field, mask_field, mask_field,
+ mask_field, mask_field, mask_field, mask_field};
uint16_t finished = 0;
uint64_t shot = 0;
@@ -343,6 +396,19 @@ class Grid {
if (i % 3 == 2) std::cout << std::endl;
}
+ std::cout << "Refs: " << 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)};
+ std::bitset<9> value = subgrids[::field(subgrid)].get_ref(field);
+ std::cout << value << " ";
+ if (j % 3 == 2) std::cout << " ";
+ }
+ std::cout << std::endl;
+ if (i % 3 == 2) std::cout << std::endl;
+ }
+
std::cout << "Board: " << std::endl;
for (uint8_t i = 0; i < 9; i++) {
for (uint8_t j = 0; j < 9; j++) {