I went away for a few days, and now I'm 5 days behind. Day 12 is about to go live, and I'm only starting this now!
This might be the first year I don't finish AoC on time. This is fine though. This is meant to be a challenge, not a chore, and if pushing myself to do it during what should be a short holiday would stress me out, then I really shouldn't try to push yourself. And neither should you. Hobbies shouldn't become chores to do.
Anyway, Day 7!
I know when the challenge is talking about an airship, it's referring to a dirigible, but I prefer to think of them as boats with propellers
The problem itself seems pretty simple. Sort the poker hands by their "rank" based on their sorting rules. Do a sorting function that can compare two hands should be all that's necessary, and their rank is simply the order that they end up in. To find the type of hand, just count repeat chars in the hand, and depending on those counts it's easy to determine the type. From there, just use the standard c++ sort()
function using a custom comparitor.
int rankHand(string cards)
{
map<char, int> counts;
for (char c: cards) counts[c]++;
bool threes = false;
int pairs = 0;
for (auto card: counts)
{
switch (card.second)
{
case 5: return 1; // 5 of a kind
case 4: return 2; // 4 of a kind
case 3: threes = true; break;
case 2: pairs++; break;
}
}
if (threes)
{
if (pairs == 1) return 3; // Full House
else return 4; // Three of a kind
}
if (pairs == 2) return 5; // Two Pair
if (pairs == 1) return 6; // One Pair
return 7; // High card
}
// ...
bool compareHands(Hand left, Hand right)
{
if (left.rank != right.rank) return left.rank > right.rank;
for (int i = 0; i < 5; i++)
{
if (left.cards[i] == right.cards[i]) continue;
return label.find(left.cards[i]) > label.find(right.cards[i]);
}
}
Of course there's a rule change! With a wildcard no less! Absolutely makes this a pain to deal with.
... or maybe not. I'm already checking card counts on a case-by-base basis. If I just update it to include the possability of wildcard jokers in the mix, it'll likely keep it relatively simple. If I just find which ever card has the highest card count, I just add the wildcards to that. It would only be for the purpose of the ranking function too, so just adding it to the beginning of that should work fine.
int rankHand(string cards)
{
map<char, int> counts;
for (char c: cards) counts[c]++;
if (counts['J'] > 0)
{
char highCard;
int highCount = 0;
for (auto card: counts)
{
if (card.first == 'J') continue;
if (card.second > highCount)
{
highCard = card.first;
highCount = card.second;
}
}
counts[highCard] += counts['J'];
counts['J'] = 0;
}
// Rest same as part 1
}
Quick and easy!