Added day 7 solution.
This commit is contained in:
parent
aa2d9cd442
commit
c4fa8f39f8
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483
|
|
@ -0,0 +1,94 @@
|
|||
import std.stdio;
|
||||
import std.algorithm;
|
||||
import std.conv;
|
||||
import std.array;
|
||||
import std.string;
|
||||
import std.ascii;
|
||||
|
||||
enum HandType : ubyte {
|
||||
FiveOfAKind = 7,
|
||||
FourOfAKind = 6,
|
||||
FullHouse = 5,
|
||||
ThreeOfAKind = 4,
|
||||
TwoPair = 3,
|
||||
OnePair = 2,
|
||||
HighCard = 1
|
||||
}
|
||||
|
||||
struct Hand {
|
||||
ubyte[5] cards;
|
||||
long bid;
|
||||
HandType type;
|
||||
}
|
||||
|
||||
HandType getType(ubyte[5] cards) {
|
||||
ubyte[15] freq;
|
||||
ubyte maxFreq = 0;
|
||||
foreach (ubyte c; cards) {
|
||||
freq[c]++;
|
||||
if (freq[c] > maxFreq) maxFreq = freq[c];
|
||||
}
|
||||
ubyte jokerFreq = freq[1];
|
||||
ubyte maxNonJokerFreq = freq[2..$].maxElement;
|
||||
ubyte nonJokerCardTypes = cast(ubyte) freq[2..$].count!(n => n != 0);
|
||||
if (maxNonJokerFreq + jokerFreq == 5) return HandType.FiveOfAKind;
|
||||
if (maxNonJokerFreq + jokerFreq == 4) return HandType.FourOfAKind;
|
||||
if (maxNonJokerFreq + jokerFreq == 3 && nonJokerCardTypes == 2) return HandType.FullHouse;
|
||||
if (maxNonJokerFreq + jokerFreq == 3) return HandType.ThreeOfAKind;
|
||||
if (maxNonJokerFreq + jokerFreq == 2 && nonJokerCardTypes == 3) return HandType.TwoPair;
|
||||
if (maxNonJokerFreq + jokerFreq == 2) return HandType.OnePair;
|
||||
return HandType.HighCard;
|
||||
}
|
||||
|
||||
bool compareHands(Hand a, Hand b) {
|
||||
if (a.type > b.type) return false;
|
||||
if (b.type > a.type) return true;
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
if (a.cards[i] > b.cards[i]) return false;
|
||||
if (b.cards[i] > a.cards[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Hand[] parseHands(string filename, bool weakJoker) {
|
||||
Hand[] hands;
|
||||
foreach (string line; File(filename).byLineCopy()) {
|
||||
string[] parts = line.split();
|
||||
Hand h;
|
||||
h.bid = parts[1].to!long;
|
||||
foreach (size_t i, char c; parts[0]) {
|
||||
if (isDigit(c)) h.cards[i] = cast(ubyte) (c - '0');
|
||||
else if (c == 'T') h.cards[i] = 10;
|
||||
else if (c == 'J') h.cards[i] = weakJoker ? 1 : 11;
|
||||
else if (c == 'Q') h.cards[i] = 12;
|
||||
else if (c == 'K') h.cards[i] = 13;
|
||||
else if (c == 'A') h.cards[i] = 14;
|
||||
}
|
||||
h.type = getType(h.cards);
|
||||
hands ~= h;
|
||||
}
|
||||
return hands;
|
||||
}
|
||||
|
||||
void computeRankedBidSum(string filename, bool weakJoker) {
|
||||
Hand[] hands = parseHands(filename, weakJoker);
|
||||
long[] bidsRanked = hands.sort!compareHands.map!(h => h.bid).array;
|
||||
long sum = 0;
|
||||
for (long i = 0; i < bidsRanked.length; i++) {
|
||||
sum += (i + 1) * bidsRanked[i];
|
||||
}
|
||||
writeln(sum);
|
||||
}
|
||||
|
||||
void part1() {
|
||||
computeRankedBidSum("input.txt", false);
|
||||
}
|
||||
|
||||
void part2() {
|
||||
computeRankedBidSum("input.txt", true);
|
||||
}
|
||||
|
||||
void main() {
|
||||
part1();
|
||||
part2();
|
||||
}
|
Loading…
Reference in New Issue