Skip to content

Commit 2af1781

Browse files
committed
Asked about unique combinations
1 parent 99a75e9 commit 2af1781

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

include/CommonConfig.hpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ namespace LOAD {
7676
* like to create an array of all possible combinations of values in
7777
* PIN_VALUES_mOhms. (included some relevant lines of my own attempts as
7878
* context)
79+
* @details Second Prompt: hanks, that seems to work perfectly! Could you
80+
* add support for deduplicating the results? ie: a constexpr variable with
81+
* the number of unique combinations, a consteval function to compute this,
82+
* and a constexpr array of the deduplicated values?
7983
*/
8084
namespace detail {
8185
// Sum of selected pins for a given bitmask
@@ -99,6 +103,61 @@ namespace LOAD {
99103

100104
return {sum_for_mask(static_cast<uint_fast8_t>(Is), values)...};
101105
}
106+
107+
// --- helpers for deduplication ---
108+
109+
template <std::size_t N>
110+
consteval etl::array<uint_fast16_t, N>
111+
sorted_copy(const etl::array<uint_fast16_t, N> &input) {
112+
auto result = input;
113+
for (std::size_t i = 0; i < N; ++i) {
114+
for (std::size_t j = i + 1; j < N; ++j) {
115+
if (result[j] < result[i]) {
116+
std::swap(result[i], result[j]);
117+
}
118+
}
119+
}
120+
return result;
121+
}
122+
123+
template <std::size_t N>
124+
consteval std::size_t
125+
count_unique(const etl::array<uint_fast16_t, N> &input) {
126+
auto sorted = sorted_copy(input);
127+
std::size_t count = 0;
128+
bool first = true;
129+
uint_fast16_t last = 0;
130+
131+
for (std::size_t i = 0; i < N; ++i) {
132+
const auto v = sorted[i];
133+
if (first || v != last) {
134+
++count;
135+
last = v;
136+
first = false;
137+
}
138+
}
139+
return count;
140+
}
141+
142+
template <std::size_t InN, std::size_t OutN>
143+
consteval etl::array<uint_fast16_t, OutN>
144+
unique_sorted(const etl::array<uint_fast16_t, InN> &input) {
145+
auto sorted = sorted_copy(input);
146+
etl::array<uint_fast16_t, OutN> out{};
147+
std::size_t out_i = 0;
148+
bool first = true;
149+
uint_fast16_t last = 0;
150+
151+
for (std::size_t i = 0; i < InN; ++i) {
152+
const auto v = sorted[i];
153+
if (first || v != last) {
154+
out[out_i++] = v;
155+
last = v;
156+
first = false;
157+
}
158+
}
159+
return out;
160+
}
102161
} // namespace detail
103162

104163
/**
@@ -115,6 +174,19 @@ namespace LOAD {
115174
constexpr etl::array<uint_fast16_t, NUM_COMBINATIONS>
116175
ALL_COMBINATIONS_mOhms = getAllCombinations(PIN_VALUES_mOhms);
117176

177+
// number of unique combination values
178+
constexpr std::size_t NUM_UNIQUE_COMBINATIONS =
179+
detail::count_unique(ALL_COMBINATIONS_mOhms);
180+
181+
static_assert(NUM_UNIQUE_COMBINATIONS <= NUM_COMBINATIONS,
182+
"NUM_UNIQUE_COMBINATIONS must be <= NUM_COMBINATIONS");
183+
184+
// deduplicated, sorted combination values
185+
constexpr etl::array<uint_fast16_t, NUM_UNIQUE_COMBINATIONS>
186+
UNIQUE_COMBINATIONS_mOhms =
187+
detail::unique_sorted<NUM_COMBINATIONS, NUM_UNIQUE_COMBINATIONS>(
188+
ALL_COMBINATIONS_mOhms);
189+
118190
// Pin 6 is connected by default in hardware
119191
constexpr uint_fast8_t INVERTED_PIN_INDEX = 5;
120192
constexpr uint8_t INVERTED_PIN_MASK = (1 << INVERTED_PIN_INDEX);

0 commit comments

Comments
 (0)