7_1.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { LoadInput } from "../common.ts";
  2. import { type CamelCardsHand, CamelCardRanking } from "./7_common.ts";
  3. const tests = [
  4. "32T3K 765",
  5. "T55J5 684",
  6. "KK677 28",
  7. "KTJJT 220",
  8. "QQQJA 483",
  9. ];
  10. const tests_reddit = [
  11. "2345A 1",
  12. "Q2KJJ 13",
  13. "Q2Q2Q 19",
  14. "T3T3J 17",
  15. "T3Q33 11",
  16. "2345J 3",
  17. "J345A 2",
  18. "32T3K 5",
  19. "T55J5 29",
  20. "KK677 7",
  21. "KTJJT 34",
  22. "QQQJA 31",
  23. "JJJJJ 37",
  24. "JAAAA 43",
  25. "AAAAJ 59",
  26. "AAAAA 61",
  27. "2AAAA 23",
  28. "2JJJJ 53",
  29. "JJJJ2 41",
  30. ];
  31. const input = await LoadInput(7);
  32. // Parse the input
  33. const parsedHands = ParseInput(input);
  34. // Sort the cards
  35. const sortedHands = parsedHands.sort(SortHands);
  36. // Find the input
  37. let totalWinnings = 0;
  38. sortedHands.forEach((hand, idx) => {
  39. totalWinnings += hand.Bid * (idx + 1);
  40. });
  41. console.log(`The total winnings are $${totalWinnings}`);
  42. /**
  43. * Parse the input
  44. *
  45. * @param {string[]} handList An array of strings represnting hands of Camel Cards and their bids
  46. * @returns {CamelCardsHand[]} An array of parsed Camel Card hands
  47. */
  48. function ParseInput(handList: string[]): CamelCardsHand[] {
  49. const output: CamelCardsHand[] = [];
  50. handList.forEach((hand) => {
  51. const [handStr, bidStr] = hand.split(" ");
  52. output.push({
  53. Hand: handStr,
  54. Bid: Number(bidStr),
  55. Rank: FindCamelCardRank(handStr),
  56. });
  57. })
  58. return output;
  59. }
  60. /**
  61. * Assign a base rank to a hand of Camel Cards
  62. *
  63. * Assigns a Camel Card Ranking to a hand of cards based on the
  64. * strength of the hand on its own.
  65. *
  66. * @param {string} hand The hand a player drew
  67. * @returns {CamelCardRanking} The ranking of the hand
  68. */
  69. function FindCamelCardRank(hand: string): CamelCardRanking {
  70. const cardFacesSorted = hand.split("").sort().join("");
  71. const fiveOfKind = new RegExp("(.)\\1{4}", "g");
  72. const fourOfKind = new RegExp("(.)\\1{3}", "g");
  73. const threeOfKind = new RegExp("(.)\\1{2}", "g");
  74. const twoOfKind = new RegExp("(.)\\1{1}", "g");
  75. // Can't get these two to work in one regex, so I'll split them for now
  76. const fullHouse_A = new RegExp("(.)\\1(.)\\2{2}", "g");
  77. const fullHouse_B = new RegExp("(.)\\1{2}(.)\\2", "g");
  78. if (cardFacesSorted.replace(twoOfKind, "").length == 5) {
  79. return CamelCardRanking.HIGH_CARD;
  80. }
  81. else if(cardFacesSorted.replace(fiveOfKind, "").length == 0) {
  82. return CamelCardRanking.FIVE_OF_A_KIND;
  83. }
  84. else if(cardFacesSorted.replace(fourOfKind, "").length == 1) {
  85. return CamelCardRanking.FOUR_OF_A_KIND;
  86. }
  87. else if(cardFacesSorted.replace(fullHouse_A, "").length == 0
  88. || cardFacesSorted.replace(fullHouse_B, "").length == 0) {
  89. return CamelCardRanking.FULL_HOUSE;
  90. }
  91. else if(cardFacesSorted.replace(threeOfKind, "").length == 2) {
  92. return CamelCardRanking.THREE_OF_A_KIND;
  93. }
  94. else if(cardFacesSorted.replace(twoOfKind, "").length == 1) {
  95. return CamelCardRanking.TWO_PAIR;
  96. }
  97. else if(cardFacesSorted.replace(twoOfKind, "").length == 3) {
  98. return CamelCardRanking.ONE_PAIR;
  99. }
  100. else {
  101. throw new Error(`Unsure how we reached this condition!\nSorted hand was: ${cardFacesSorted}`);
  102. }
  103. }
  104. /**
  105. * Compare two hands of Camel Cards for sorting
  106. */
  107. function SortHands(a: CamelCardsHand, b: CamelCardsHand): number {
  108. if (a.Rank < b.Rank) { return -1; }
  109. if (a.Rank > b.Rank) { return 1; }
  110. // Replace the letters with something easier to compare
  111. const aHand = a.Hand.replaceAll("A", "Z").replaceAll("K", "Y").replaceAll("Q", "X").replaceAll("J", "W").replaceAll("T", "V");
  112. const bHand = b.Hand.replaceAll("A", "Z").replaceAll("K", "Y").replaceAll("Q", "X").replaceAll("J", "W").replaceAll("T", "V");
  113. for (let i = 0; i < 5; i++) {
  114. if (aHand[i] < bHand[i]) {
  115. return -1;
  116. }
  117. if (aHand[i] > bHand[i]) {
  118. return 1;
  119. }
  120. }
  121. return 0;
  122. }