summaryrefslogtreecommitdiff
path: root/day-7/script.ts
blob: 9b70cfa59118c33e2627caa797c3477c529d6ec7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import fs from "fs";

enum HandType {
  highCard,
  onePair,
  twoPair,
  threeOfAKind,
  fullHouse,
  fourOfAKind,
  fiveOfAKind,
}

const cardStrength = [
  "J",
  "2",
  "3",
  "4",
  "5",
  "6",
  "7",
  "8",
  "9",
  "T",
  "Q",
  "K",
  "A",
];

function classifyHand(hand: string) {
  const cards = hand.split("");

  const jokerCount = cards.filter((card) => card === "J").length;

  const counts = Array.from(new Set(cards))
    .filter((card) => card !== "J")
    .map((card) => cards.filter((c) => c === card).length)
    .sort()
    .reverse();

  const biggestCount = (counts[0] || 0) + jokerCount;

  if (biggestCount == 5) return HandType.fiveOfAKind;
  if (biggestCount == 4) return HandType.fourOfAKind;
  if (biggestCount == 3 && counts[1] == 2) return HandType.fullHouse;
  if (biggestCount == 3) return HandType.threeOfAKind;
  if (biggestCount == 2 && counts[1] == 2) return HandType.twoPair;
  if (biggestCount == 2) return HandType.onePair;
  return HandType.highCard;
}

const input = fs
  .readFileSync("./input.txt")
  .toString()
  .split("\n")
  .slice(0, -1)
  .map((line) => {
    const match = line.match(/(.....) (\d+)/);
    if (!match) throw new Error("Unexpected format");
    return {
      hand: match[1],
      bid: Number(match[2]),
      type: classifyHand(match[1]),
    };
  })
  .sort((a, b) => {
    const diff = a.type - b.type;
    if (diff) return diff;

    return [0, 1, 2, 3, 4].reduce((acc, index) => {
      return acc
        ? acc
        : cardStrength.indexOf(a.hand[index]) -
            cardStrength.indexOf(b.hand[index]);
    }, 0);
  })
  .reduce((sum, item, index) => sum + item.bid * (index + 1), 0);

console.log({ input });