Skip to content

Instantly share code, notes, and snippets.

@vadim2404
Created December 9, 2023 19:07
Show Gist options
  • Save vadim2404/5a7a8bd180b0004ca453dbf353b3afce to your computer and use it in GitHub Desktop.
Save vadim2404/5a7a8bd180b0004ca453dbf353b3afce to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
from collections import Counter
from enum import IntEnum
from typing import Mapping, Tuple
CARDS: Tuple[str, ...] = ('J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A', )
CARDS_VALUES: Mapping[str, int] = {c: i for i, c in enumerate(CARDS, start=2)}
class HandRank(IntEnum):
HIGH_CARD = 1
PAIR = 2
TWO_PAIRS = 3
THREE_OF_A_KIND = 4
FULL_HOUSE = 5
FOUR_OF_A_KIND = 6
FIVE_OF_A_KIND = 7
class Hand:
__slots__ = ('cards', 'bid', 'rank', 'card_values', )
def __init__(self, cards: str, bid: int):
c = Counter(cards)
self.cards = cards
self.bid = bid
self.card_values = [CARDS_VALUES[c] for c in cards]
try:
value = c.pop('J')
if not c:
c['A'] = value
else:
c[c.most_common(1)[0][0]] += value
except KeyError:
pass
match len(c):
case 1:
self.rank = HandRank.FIVE_OF_A_KIND
case 2:
self.rank = HandRank.FOUR_OF_A_KIND if 4 in c.values() else HandRank.FULL_HOUSE
case 3:
self.rank = HandRank.THREE_OF_A_KIND if 3 in c.values() else HandRank.TWO_PAIRS
case 4:
self.rank = HandRank.PAIR
case _:
self.rank = HandRank.HIGH_CARD
def __lt__(self, other: 'Hand') -> bool:
return (self.rank, self.card_values) < (other.rank, other.card_values)
def __repr__(self) -> str:
return f"{self.cards} {self.bid}"
with open("input.txt") as f:
hands = []
for line in f:
cards, bid = line.strip().split(maxsplit=1)
hands.append(Hand(cards, int(bid)))
hands.sort()
print(sum(i * h.bid for i, h in enumerate(hands, start=1)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment