Skip to content

Commit

Permalink
Update matchings randomization. (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
acodcha committed Oct 19, 2023
1 parent ea1f71b commit 2ae798d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 34 deletions.
56 changes: 22 additions & 34 deletions source/Matchings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,35 @@ class Matchings {
random_generator.seed(random_seed.value());
}

// Initialize the giftees.
std::vector<std::string> giftees(participants.size());
// Obtain the participant names.
std::vector<std::string> participant_names(participants.size());
{
std::size_t index = 0;
for (const Participant& participant : participants) {
giftees[index] = participant.Name();
participant_names[index] = participant.Name();
++index;
}
}

// Shuffle the giftees.
do {
std::shuffle(giftees.begin(), giftees.end(), random_generator);
} while (!IsValid(participants, giftees));

// Store the gifters and giftees.
{
std::size_t index = 0;
for (const Participant& participant : participants) {
gifters_to_giftees_.emplace(participant.Name(), giftees[index]);
++index;
}
// Shuffle the participant names.
std::shuffle(
participant_names.begin(), participant_names.end(), random_generator);

// Create the matchings between gifters and giftees. Each participant in the
// shuffled sequence is a gifter, and their giftee is the next participant
// in the shuffled sequence. This results in one large cyclic list rather
// than a graph and guarantees that gifters cannot be their own giftees. For
// example, consider the sequence [Alice, Bob, Claire, David]. After
// shuffling, suppose this sequence is [Claire, Bob, David, Alice]. The
// matchings are thus: Claire->Bob, Bob->David, David->Alice, and
// Alice->Claire.
for (std::size_t gifter_index = 0; gifter_index < participant_names.size();
++gifter_index) {
const std::size_t giftee_index =
gifter_index + 1 < participant_names.size() ? gifter_index + 1 : 0;

gifters_to_giftees_.emplace(
participant_names[gifter_index], participant_names[giftee_index]);
}

std::cout
Expand Down Expand Up @@ -220,25 +227,6 @@ class Matchings {
}

private:
// Checks whether the assignment of gifters and giftees is valid. To be valid,
// no gifter must be assigned themselves as their giftee.
bool IsValid(const std::set<Participant>& gifters,
const std::vector<std::string>& giftees) const {
if (gifters.size() <= 1) {
return true;
}

std::size_t index = 0;
for (const Participant& gifter : gifters) {
if (index >= giftees.size() || gifter.Name() == giftees[index]) {
return false;
}
++index;
}

return true;
}

// Map of gifter participant names to giftee participant names. For example,
// the map element {Alice, Bob} means that Alice is the gifter and Bob is the
// giftee, such that Alice is Bob's Secret Santa.
Expand Down
3 changes: 3 additions & 0 deletions test/Matchings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ TEST(Matchings, ConstructorFromNoParticipants) {
TEST(Matchings, ConstructorFromOneParticipant) {
const Matchings matchings{{CreateSampleParticipantA()}};
EXPECT_EQ(matchings.GiftersToGiftees().size(), 1);
EXPECT_NE(matchings.GiftersToGiftees().find("Alice Smith"),
matchings.GiftersToGiftees().cend());
EXPECT_EQ(matchings.GiftersToGiftees().at("Alice Smith"), "Alice Smith");
}

TEST(Matchings, ConstructorFromThreeParticipants) {
Expand Down

0 comments on commit 2ae798d

Please sign in to comment.