import { LoadInput } from "../common.ts"; import { type CamelCardsHand, CamelCardRanking } from "./7_common.ts"; const tests = [ "32T3K 765", "T55J5 684", "KK677 28", "KTJJT 220", "QQQJA 483", ]; const tests_reddit = [ "2345A 1", "Q2KJJ 13", "Q2Q2Q 19", "T3T3J 17", "T3Q33 11", "2345J 3", "J345A 2", "32T3K 5", "T55J5 29", "KK677 7", "KTJJT 34", "QQQJA 31", "JJJJJ 37", "JAAAA 43", "AAAAJ 59", "AAAAA 61", "2AAAA 23", "2JJJJ 53", "JJJJ2 41", ]; const input = await LoadInput(7); // Parse the input const parsedHands = ParseInput(input); // Sort the cards const sortedHands = parsedHands.sort(SortHands); // Find the input let totalWinnings = 0; sortedHands.forEach((hand, idx) => { totalWinnings += hand.Bid * (idx + 1); }); console.log(`The total winnings are $${totalWinnings}`); /** * Parse the input * * @param {string[]} handList An array of strings represnting hands of Camel Cards and their bids * @returns {CamelCardsHand[]} An array of parsed Camel Card hands */ function ParseInput(handList: string[]): CamelCardsHand[] { const output: CamelCardsHand[] = []; handList.forEach((hand) => { const [handStr, bidStr] = hand.split(" "); output.push({ Hand: handStr, Bid: Number(bidStr), Rank: FindCamelCardRank(handStr), }); }) return output; } /** * Assign a base rank to a hand of Camel Cards * * Assigns a Camel Card Ranking to a hand of cards based on the * strength of the hand on its own. * * @param {string} hand The hand a player drew * @returns {CamelCardRanking} The ranking of the hand */ function FindCamelCardRank(hand: string): CamelCardRanking { const cardFacesSorted = hand.split("").sort().join(""); const fiveOfKind = new RegExp("(.)\\1{4}", "g"); const fourOfKind = new RegExp("(.)\\1{3}", "g"); const threeOfKind = new RegExp("(.)\\1{2}", "g"); const twoOfKind = new RegExp("(.)\\1{1}", "g"); // Can't get these two to work in one regex, so I'll split them for now const fullHouse_A = new RegExp("(.)\\1(.)\\2{2}", "g"); const fullHouse_B = new RegExp("(.)\\1{2}(.)\\2", "g"); if (cardFacesSorted.replace(twoOfKind, "").length == 5) { return CamelCardRanking.HIGH_CARD; } else if(cardFacesSorted.replace(fiveOfKind, "").length == 0) { return CamelCardRanking.FIVE_OF_A_KIND; } else if(cardFacesSorted.replace(fourOfKind, "").length == 1) { return CamelCardRanking.FOUR_OF_A_KIND; } else if(cardFacesSorted.replace(fullHouse_A, "").length == 0 || cardFacesSorted.replace(fullHouse_B, "").length == 0) { return CamelCardRanking.FULL_HOUSE; } else if(cardFacesSorted.replace(threeOfKind, "").length == 2) { return CamelCardRanking.THREE_OF_A_KIND; } else if(cardFacesSorted.replace(twoOfKind, "").length == 1) { return CamelCardRanking.TWO_PAIR; } else if(cardFacesSorted.replace(twoOfKind, "").length == 3) { return CamelCardRanking.ONE_PAIR; } else { throw new Error(`Unsure how we reached this condition!\nSorted hand was: ${cardFacesSorted}`); } } /** * Compare two hands of Camel Cards for sorting */ function SortHands(a: CamelCardsHand, b: CamelCardsHand): number { if (a.Rank < b.Rank) { return -1; } if (a.Rank > b.Rank) { return 1; } // Replace the letters with something easier to compare const aHand = a.Hand.replaceAll("A", "Z").replaceAll("K", "Y").replaceAll("Q", "X").replaceAll("J", "W").replaceAll("T", "V"); const bHand = b.Hand.replaceAll("A", "Z").replaceAll("K", "Y").replaceAll("Q", "X").replaceAll("J", "W").replaceAll("T", "V"); for (let i = 0; i < 5; i++) { if (aHand[i] < bHand[i]) { return -1; } if (aHand[i] > bHand[i]) { return 1; } } return 0; }