aoc-2023/day_7/solve_2.ts

93 lines
2.6 KiB
TypeScript
Raw Permalink Normal View History

2024-12-09 22:41:02 +09:00
type CardHand = string;
const BidOfHand = ["J", "2", "3", "4", "5", "6", "7", "8", "9", "T", "Q", "K", "A"];
const StrengthOfHand = {
"J": 0,
"2": 1,
"3": 2,
"4": 3,
"5": 4,
"6": 5,
"7": 6,
"8": 7,
"9": 8,
"T": 9,
"Q": 10,
"K": 11,
"A": 12,
}
enum HandType {
FiveOfAKind = 6,
FourOfAKind = 5,
FullHouse = 4,
ThreeOfAKind = 3,
TwoPair = 2,
OnePair = 1,
HighCard = 0
}
function getTypeOfHand(hand: CardHand): HandType{
const cards = hand.split("");
const counter = new Array(13).fill(0);
for (let i = 0; i < cards.length; i++){
const card = cards[i];
if (!(card in StrengthOfHand)) {
throw new Error(`invalid card: ${card}`);
}
const index = StrengthOfHand[card as keyof typeof StrengthOfHand];
counter[index] += 1;
}
const jokerCount = counter[StrengthOfHand["J"]];
counter[StrengthOfHand["J"]] = 0;
const sorted = counter.sort((a, b) => b - a);
// joker can act like whatever card would make the hand the strongest type possible
sorted[0] += jokerCount;
// five of a kind
if (sorted[0] === 5) return HandType.FiveOfAKind;
// four of a kind
if (sorted[0] === 4) return HandType.FourOfAKind;
// full house
if (sorted[0] === 3 && sorted[1] === 2) return HandType.FullHouse;
// three of a kind
if (sorted[0] === 3) return HandType.ThreeOfAKind;
// two pair
if (sorted[0] === 2 && sorted[1] === 2) return HandType.TwoPair;
// one pair
if (sorted[0] === 2) return HandType.OnePair;
// high card
return HandType.HighCard;
}
function handCompare(a: CardHand, b: CardHand) {
const aType = getTypeOfHand(a);
const bType = getTypeOfHand(b);
if (aType < bType) return -1;
if (aType > bType) return 1;
// aType === bType
for (let i = 0; i < a.length; i++){
const aStrength = StrengthOfHand[a[i] as keyof typeof StrengthOfHand];
const bStrength = StrengthOfHand[b[i] as keyof typeof StrengthOfHand];
if (aStrength < bStrength) return -1;
if (aStrength > bStrength) return 1;
}
// aStrength === bStrength
return 0;
}
const input = await Deno.readTextFile("example.txt");
const lines = input.split("\n").map(x => x.trim()).filter(x => x.length > 0)
const data = lines.map(x => {
const [hands, bid] = x.split(" ");
return {hands, bid:parseInt(bid)};
});
data.sort((a, b) => handCompare(a.hands, b.hands));
console.log(data)
const sum = data.map((x,i)=> x.bid * (i+1)).reduce((a, b) => a + b, 0);
console.log(sum);