Make sort in PollManager::get_vote_percentage more stable.

This commit is contained in:
levlam 2022-01-11 21:52:29 +03:00
parent e89b3eeb9b
commit e592ca4b83
2 changed files with 9 additions and 3 deletions

View File

@ -451,7 +451,9 @@ vector<int32> PollManager::get_vote_percentage(const vector<int32> &voter_counts
std::unordered_map<int32, Option> options;
for (size_t i = 0; i < result.size(); i++) {
auto &option = options[voter_counts[i]];
if (option.pos == -1) {
option.pos = narrow_cast<int32>(i);
}
option.count++;
}
vector<Option> sorted_options;
@ -473,7 +475,11 @@ vector<int32> PollManager::get_vote_percentage(const vector<int32> &voter_counts
// prefer options with smallest gap
return gap[lhs.pos] < gap[rhs.pos];
}
return lhs.count > rhs.count; // prefer more popular options
if (lhs.count != rhs.count) {
// prefer more popular options
return lhs.count > rhs.count;
}
return lhs.pos < rhs.pos; // prefer the first encountered option
});
// dynamic programming or brute force can give perfect result, but for now we use simple gready approach

View File

@ -23,6 +23,7 @@ TEST(Poll, get_vote_percentage) {
check_vote_percentage({999}, 999, {100});
check_vote_percentage({0}, 0, {0});
check_vote_percentage({2, 1}, 3, {67, 33});
check_vote_percentage({4, 1, 1}, 6, {66, 17, 17});
check_vote_percentage({100, 100}, 200, {50, 50});
check_vote_percentage({101, 99}, 200, {50, 50});
check_vote_percentage({102, 98}, 200, {51, 49});
@ -51,7 +52,6 @@ TEST(Poll, get_vote_percentage) {
check_vote_percentage({1234, 2301, 3500, 2841}, 9876,
{12 /* 12.49 */, 23 /* 23.29 */, 35 /* 35.43 */, 29 /* 28.76 */});
check_vote_percentage({200, 200, 200, 270, 270, 60}, 1200, {17, 17, 17, 22, 22, 5});
check_vote_percentage({200, 200, 200, 270, 270, 60}, 1200, {17, 17, 17, 22, 22, 5});
check_vote_percentage({200, 200, 200, 300, 240, 60}, 1200, {16, 16, 16, 25, 20, 5});
check_vote_percentage({200, 200, 200, 250, 250, 20}, 1120, {18, 18, 18, 22, 22, 2});
check_vote_percentage({200, 200, 200, 250, 250, 40}, 1140, {17, 17, 17, 22, 22, 4});