@@ -26,29 +26,40 @@ class CamelCardsHand:
26
26
@cached_property
27
27
def hand_type_strength (self ) -> int :
28
28
card_value_counts = {
29
- v : sum (1 for c in self .cards if c == v ) for v in set (self .cards )
29
+ v : sum (1 for c in self .cards if c == v )
30
+ for v in {card for card in self .cards if card != 0 }
30
31
}
31
32
card_counts = card_value_counts .values ()
32
33
33
- if set (card_counts ) == {5 }:
34
+ num_jokers = sum (1 for c in self .cards if c == 0 )
35
+
36
+ if max (card_counts or [0 ]) + num_jokers == 5 :
34
37
return FIVE_OF_A_KIND
35
- elif set (card_counts ) == { 4 , 1 } :
38
+ elif max (card_counts or [ 0 ]) + num_jokers == 4 :
36
39
return FOUR_OF_A_KIND
37
- elif set (card_counts ) == {3 , 2 }:
40
+ elif set (card_counts ) == {3 , 2 } or (
41
+ sorted (card_counts ) == [2 , 2 ] and num_jokers == 1
42
+ ):
38
43
return FULL_HOUSE
39
- elif set (card_counts ) == { 3 , 1 } :
44
+ elif max (card_counts or [ 0 ]) + num_jokers == 3 :
40
45
return THREE_OF_A_KIND
41
46
elif sorted (card_counts ) == [1 , 2 , 2 ]:
42
47
return TWO_PAIR
43
- elif 2 in card_counts :
48
+ elif 2 in card_counts or num_jokers == 1 :
44
49
return ONE_PAIR
45
50
else :
46
51
return HIGH_CARD
47
52
48
- def __eq__ (self , other : "CamelCardsHand" ) -> bool :
53
+ def __eq__ (self , other ) -> bool :
54
+ if not isinstance (other , CamelCardsHand ):
55
+ return NotImplemented
56
+
49
57
return self .cards == other .cards
50
58
51
- def __lt__ (self , other : "CamelCardsHand" ) -> bool :
59
+ def __lt__ (self , other ) -> bool :
60
+ if not isinstance (other , CamelCardsHand ):
61
+ return NotImplemented
62
+
52
63
if self .hand_type_strength < other .hand_type_strength :
53
64
return True
54
65
if self .hand_type_strength == other .hand_type_strength :
@@ -62,12 +73,12 @@ def __lt__(self, other: "CamelCardsHand") -> bool:
62
73
return False
63
74
64
75
@classmethod
65
- def from_input (cls , input_line : str ) -> "CamelCardsHand" :
76
+ def from_input (cls , input_line : str , joker_rule : bool = False ) -> "CamelCardsHand" :
66
77
cards_part , bid_part = input_line .split ()
67
78
68
79
values_map = {
69
80
"T" : 10 ,
70
- "J" : 11 ,
81
+ "J" : 0 if joker_rule else 11 ,
71
82
"Q" : 12 ,
72
83
"K" : 13 ,
73
84
"A" : 14 ,
@@ -79,7 +90,7 @@ def from_input(cls, input_line: str) -> "CamelCardsHand":
79
90
80
91
return cls (
81
92
bid = int (bid_part ),
82
- cards = card_values ,
93
+ cards = card_values , # type: ignore
83
94
)
84
95
85
96
@@ -90,7 +101,9 @@ def part_1(cards_input: list[str]) -> int:
90
101
91
102
92
103
def part_2 (cards_input : list [str ]) -> int :
93
- pass
104
+ hands = [CamelCardsHand .from_input (line , joker_rule = True ) for line in cards_input ]
105
+
106
+ return sum (i * hand .bid for i , hand in enumerate (sorted (hands ), start = 1 ))
94
107
95
108
96
109
if __name__ == "__main__" :
0 commit comments