commit aded653ae1e36bb63d3d9663569a5b84e930a3df
parent 373064734d5b09ee3e8181d04f6a92396fb20a65
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Tue, 9 Apr 2024 23:45:18 +0200
Cleanup code with helper functions
Diffstat:
M | main.cpp | | | 136 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
1 file changed, 57 insertions(+), 79 deletions(-)
diff --git a/main.cpp b/main.cpp
@@ -46,6 +46,47 @@ struct row_col_t {
};
class Ref {
+ auto get_pointing(uint16_t mask, uint16_t &seen) const {
+ std::vector<std::tuple<uint8_t, uint8_t>> res;
+
+ for (uint8_t i = 0; i < 9; i++) {
+ const uint8_t popcnt = std::popcount(ref[i]);
+ if (popcnt < 2 || popcnt > 3) continue;
+
+ if ((seen & (1 << i)) == 0) {
+ uint16_t cmask = mask;
+ for (uint8_t k = 0; k < 3; k++, cmask <<= 3) {
+ if (std::popcount(uint16_t(cmask & ref[i])) != popcnt) continue;
+ seen |= 1 << i;
+ res.emplace_back(k, i);
+ break;
+ }
+ }
+ }
+
+ return res;
+ }
+
+ void get_indices(uint8_t indices[9], uint16_t mask) const {
+ uint8_t size = 0;
+ while (mask) {
+ const uint8_t idx = std::countr_zero(mask);
+ indices[size++] = idx;
+ mask ^= 1ull << idx;
+ }
+ }
+
+ using hidden_t = std::tuple<uint8_t, uint16_t>;
+ using hiddens_t = std::vector<hidden_t>;
+
+ void get_hidden_changes(uint8_t fields[9], uint16_t mask, uint8_t n, hiddens_t &vec) const {
+ for (uint8_t i = 0; i < n; i++) {
+ const uint16_t change = value[fields[i]] & ~(value[fields[i]] & mask);
+ if (!change) continue;
+ vec.emplace_back(fields[i], change);
+ }
+ }
+
public:
uint16_t get(uint8_t field) const { return value[field]; }
uint16_t get_ref(uint8_t value) const { return ref[value]; }
@@ -67,45 +108,13 @@ class Ref {
}
auto get_pointing_row() const {
- std::vector<std::tuple<uint8_t, uint8_t>> res;
-
- for (uint8_t i = 0; i < 9; i++) {
- const uint8_t popcnt = std::popcount(ref[i]);
- if (popcnt < 2 || popcnt > 3) continue;
-
- if ((seen_point_row & (1 << i)) == 0) {
- uint16_t row_mask = 0x7;
- for (uint8_t k = 0; k < 3; k++, row_mask <<= 3) {
- if (std::popcount(uint16_t(row_mask & ref[i])) != popcnt) continue;
- seen_point_row |= 1 << i;
- res.emplace_back(k, i);
- break;
- }
- }
- }
-
- return res;
+ static const uint16_t row_mask = 0x7;
+ return get_pointing(row_mask, seen_point_row);
}
auto get_pointing_col() const {
- std::vector<std::tuple<uint8_t, uint8_t>> res;
-
- for (uint8_t i = 0; i < 9; i++) {
- const uint8_t popcnt = std::popcount(ref[i]);
- if (popcnt < 2 || popcnt > 3) continue;
-
- if ((seen_point_col & (1 << i)) == 0) {
- uint16_t col_mask = 0x49;
- for (uint8_t k = 0; k < 3; k++, col_mask <<= 3) {
- if (std::popcount(uint16_t(col_mask & ref[i])) != popcnt) continue;
- seen_point_col |= 1 << i;
- res.emplace_back(k, i);
- break;
- }
- }
- }
-
- return res;
+ static const uint16_t col_mask = 0x49;
+ return get_pointing(col_mask, seen_point_col);
}
auto get_hidden_singles() const {
@@ -120,7 +129,7 @@ class Ref {
}
auto get_hidden_pairs() const {
- std::vector<std::tuple<uint8_t, uint16_t>> res;
+ hiddens_t res;
for (uint8_t i = 0; i < 9; i++) {
if (std::popcount(ref[i]) != 2) continue;
@@ -133,21 +142,10 @@ class Ref {
seen_hidden_pair |= 1ul << j;
static uint8_t fields[9];
- uint8_t size = 0;
-
- uint16_t tval = ref[i];
- while (tval) {
- const uint8_t idx = std::countr_zero(tval);
- fields[size++] = idx;
- tval ^= 1ull << idx;
- }
+ get_indices(fields, ref[i]);
- uint16_t mask = (1 << i) | (1 << j);
- for (uint8_t i = 0; i < 2; i++) {
- const uint16_t change = value[fields[i]] & ~(value[fields[i]] & mask);
- if (!change) continue;
- res.emplace_back(fields[i], change);
- }
+ const uint16_t mask = (1 << i) | (1 << j);
+ get_hidden_changes(fields, mask, 2, res);
}
}
@@ -155,7 +153,7 @@ class Ref {
}
auto get_hidden_triplets() const {
- std::vector<std::tuple<uint8_t, uint16_t>> res;
+ hiddens_t res;
for (uint8_t i = 0; i < 9; i++) {
if (std::popcount(ref[i]) < 2) continue;
@@ -169,7 +167,7 @@ class Ref {
if (std::popcount(ref[k]) < 2) continue;
if (seen_hidden_triplet & (1ul << k)) continue;
- uint16_t val = ref[i] | ref[j] | ref[k];
+ const uint16_t val = ref[i] | ref[j] | ref[k];
if (std::popcount(val) != 3) continue;
seen_hidden_triplet |= 1ul << i;
@@ -177,21 +175,10 @@ class Ref {
seen_hidden_triplet |= 1ul << k;
static uint8_t fields[9];
- uint8_t size = 0;
-
- uint16_t tval = val;
- while (tval) {
- const uint8_t idx = std::countr_zero(tval);
- fields[size++] = idx;
- tval ^= 1ull << idx;
- }
+ get_indices(fields, val);
uint16_t mask = (1 << i) | (1 << j) | (1 << k);
- for (uint8_t i = 0; i < 3; i++) {
- const uint16_t change = value[fields[i]] & ~(value[fields[i]] & mask);
- if (!change) continue;
- res.emplace_back(fields[i], change);
- }
+ get_hidden_changes(fields, mask, 3, res);
}
}
}
@@ -227,21 +214,10 @@ class Ref {
seen_hidden_quads |= 1ul << l;
static uint8_t fields[9];
- uint8_t size = 0;
-
- uint16_t tval = val;
- while (tval) {
- const uint8_t idx = std::countr_zero(tval);
- fields[size++] = idx;
- tval ^= 1ull << idx;
- }
+ get_indices(fields, val);
uint16_t mask = (1 << i) | (1 << j) | (1 << k) | (1 << l);
- for (uint8_t i = 0; i < 4; i++) {
- const uint16_t change = value[fields[i]] & ~(value[fields[i]] & mask);
- if (!change) continue;
- res.emplace_back(fields[i], change);
- }
+ get_hidden_changes(fields, mask, 4, res);
}
}
}
@@ -323,6 +299,7 @@ class Ref {
auto get_naked_quads() const {
std::vector<std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>> res;
+
for (uint8_t i = 0; i < 9; i++) {
if (this->res[i]) continue;
if (seen_naked_quad & (1ul << i)) continue;
@@ -362,6 +339,7 @@ class Ref {
private:
uint16_t value[9] = {mask_field, mask_field, mask_field, mask_field, mask_field,
mask_field, mask_field, mask_field, mask_field};
+
uint16_t ref[9] = {mask_field, mask_field, mask_field, mask_field, mask_field,
mask_field, mask_field, mask_field, mask_field};