forked from Bananymous/banan-os
AOC2023: optimize hand score calculation
This commit is contained in:
parent
a872efdef2
commit
536bb74d53
|
@ -1,5 +1,6 @@
|
||||||
#include <BAN/Vector.h>
|
#include <BAN/Vector.h>
|
||||||
#include <BAN/String.h>
|
#include <BAN/String.h>
|
||||||
|
#include <BAN/Swap.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -62,44 +63,40 @@ i64 hand_score(const Hand& hand, bool joker)
|
||||||
{
|
{
|
||||||
if (isdigit(c))
|
if (isdigit(c))
|
||||||
cnt[c - '0' + 0]++;
|
cnt[c - '0' + 0]++;
|
||||||
else if (c == 'J')
|
else if (joker && c == 'J')
|
||||||
joker_count++;
|
joker_count++;
|
||||||
else
|
else
|
||||||
cnt[c - 'A' + 10]++;
|
cnt[c - 'A' + 10]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!joker)
|
i64 freq_max1 = 0;
|
||||||
|
i64 freq_max2 = 0;
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
{
|
{
|
||||||
cnt['J' - 'A' + 10] = joker_count;
|
if (cnt[i] > freq_max1)
|
||||||
joker_count = 0;
|
{
|
||||||
|
freq_max2 = freq_max1;
|
||||||
|
freq_max1 = cnt[i];
|
||||||
}
|
}
|
||||||
|
else if (cnt[i] > freq_max2)
|
||||||
|
{
|
||||||
|
freq_max2 = cnt[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freq_max1 += joker_count;
|
||||||
|
|
||||||
for (size_t i = 0; i < 36; i++)
|
if (freq_max1 == 5)
|
||||||
if (cnt[i] + joker_count >= 5)
|
|
||||||
return 6'000'000 + hand_score_no_type(hand, joker);
|
return 6'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
if (freq_max1 == 4)
|
||||||
for (size_t i = 0; i < 36; i++)
|
|
||||||
if (cnt[i] + joker_count >= 4)
|
|
||||||
return 5'000'000 + hand_score_no_type(hand, joker);
|
return 5'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
if (freq_max1 == 3 && freq_max2 == 2)
|
||||||
for (size_t i = 0; i < 36; i++)
|
|
||||||
for (size_t j = 0; j < 36; j++)
|
|
||||||
if (i != j && cnt[i] + joker_count >= 3 && cnt[j] >= 2)
|
|
||||||
return 4'000'000 + hand_score_no_type(hand, joker);
|
return 4'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
if (freq_max1 == 3)
|
||||||
for (size_t i = 0; i < 36; i++)
|
|
||||||
if (cnt[i] + joker_count >= 3)
|
|
||||||
return 3'000'000 + hand_score_no_type(hand, joker);
|
return 3'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
if (freq_max1 == 2 && freq_max2 == 2)
|
||||||
for (size_t i = 0; i < 36; i++)
|
|
||||||
for (size_t j = 0; j < 36; j++)
|
|
||||||
if (i != j && cnt[i] + joker_count >= 2 && cnt[j] >= 2)
|
|
||||||
return 2'000'000 + hand_score_no_type(hand, joker);
|
return 2'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
if (freq_max1 == 2)
|
||||||
for (size_t i = 0; i < 36; i++)
|
|
||||||
if (cnt[i] + joker_count >= 2)
|
|
||||||
return 1'000'000 + hand_score_no_type(hand, joker);
|
return 1'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
|
||||||
return hand_score_no_type(hand, joker);
|
return hand_score_no_type(hand, joker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,11 +110,10 @@ i64 puzzle(FILE* fp, bool joker)
|
||||||
BAN::StringView line(buffer);
|
BAN::StringView line(buffer);
|
||||||
if (line.size() < 7)
|
if (line.size() < 7)
|
||||||
continue;
|
continue;
|
||||||
|
MUST(hands.emplace_back(
|
||||||
Hand hand;
|
line.substring(0, 5),
|
||||||
hand.hand = line.substring(0, 5);
|
parse_i64(line.substring(6))
|
||||||
hand.bid = parse_i64(line.substring(6));
|
));
|
||||||
MUST(hands.push_back(hand));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very slow sorting algorithm
|
// Very slow sorting algorithm
|
||||||
|
@ -129,9 +125,7 @@ i64 puzzle(FILE* fp, bool joker)
|
||||||
i64 r_score = hand_score(hands[j], joker);
|
i64 r_score = hand_score(hands[j], joker);
|
||||||
if (r_score > l_score)
|
if (r_score > l_score)
|
||||||
{
|
{
|
||||||
Hand tmp = BAN::move(hands[i]);
|
BAN::swap(hands[i], hands[j]);
|
||||||
hands[i] = BAN::move(hands[j]);
|
|
||||||
hands[j] = BAN::move(tmp);
|
|
||||||
l_score = r_score;
|
l_score = r_score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue