Skip to content

Commit d34f6b7

Browse files
committed
y2023 d7 p1
1 parent ca45d36 commit d34f6b7

File tree

3 files changed

+1121
-0
lines changed

3 files changed

+1121
-0
lines changed

src/advent_of_code/y2023/d7.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from dataclasses import dataclass
2+
from functools import cached_property, total_ordering
3+
4+
from advent_of_code.util import format_solution, puzzle_input
5+
6+
HIGH_CARD = 1
7+
ONE_PAIR = 2
8+
TWO_PAIR = 3
9+
THREE_OF_A_KIND = 4
10+
FULL_HOUSE = 5
11+
FOUR_OF_A_KIND = 6
12+
FIVE_OF_A_KIND = 7
13+
14+
15+
@total_ordering
16+
@dataclass(frozen=True)
17+
class CamelCardsHand:
18+
"""
19+
Represent a hand with a bid in a game of Camel Cards
20+
"""
21+
22+
bid: int
23+
24+
cards: tuple[int, int, int, int, int]
25+
26+
@cached_property
27+
def hand_type_strength(self) -> int:
28+
card_value_counts = {
29+
v: sum(1 for c in self.cards if c == v) for v in set(self.cards)
30+
}
31+
card_counts = card_value_counts.values()
32+
33+
if set(card_counts) == {5}:
34+
return FIVE_OF_A_KIND
35+
elif set(card_counts) == {4, 1}:
36+
return FOUR_OF_A_KIND
37+
elif set(card_counts) == {3, 2}:
38+
return FULL_HOUSE
39+
elif set(card_counts) == {3, 1}:
40+
return THREE_OF_A_KIND
41+
elif sorted(card_counts) == [1, 2, 2]:
42+
return TWO_PAIR
43+
elif 2 in card_counts:
44+
return ONE_PAIR
45+
else:
46+
return HIGH_CARD
47+
48+
def __eq__(self, other: "CamelCardsHand") -> bool:
49+
return self.cards == other.cards
50+
51+
def __lt__(self, other: "CamelCardsHand") -> bool:
52+
if self.hand_type_strength < other.hand_type_strength:
53+
return True
54+
if self.hand_type_strength == other.hand_type_strength:
55+
for self_num, other_num in zip(self.cards, other.cards):
56+
if self_num < other_num:
57+
return True
58+
elif self_num == other_num:
59+
continue
60+
else:
61+
return False
62+
return False
63+
64+
@classmethod
65+
def from_input(cls, input_line: str) -> "CamelCardsHand":
66+
cards_part, bid_part = input_line.split()
67+
68+
values_map = {
69+
"T": 10,
70+
"J": 11,
71+
"Q": 12,
72+
"K": 13,
73+
"A": 14,
74+
}
75+
76+
card_values = tuple(
77+
values_map[v] if v in values_map else int(v) for v in cards_part
78+
)
79+
80+
return cls(
81+
bid=int(bid_part),
82+
cards=card_values,
83+
)
84+
85+
86+
def part_1(cards_input: list[str]) -> int:
87+
hands = [CamelCardsHand.from_input(line) for line in cards_input]
88+
89+
return sum(i * hand.bid for i, hand in enumerate(sorted(hands), start=1))
90+
91+
92+
def part_2(cards_input: list[str]) -> int:
93+
pass
94+
95+
96+
if __name__ == "__main__":
97+
puzzle = puzzle_input(2023, 7)
98+
99+
print(
100+
format_solution(
101+
solver_p1=lambda: part_1(puzzle),
102+
solver_p2=lambda: part_2(puzzle),
103+
)
104+
)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy