-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday07.py
More file actions
155 lines (123 loc) · 3.25 KB
/
day07.py
File metadata and controls
155 lines (123 loc) · 3.25 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from enum import Enum
from collections import Counter
from functools import cmp_to_key
class HandType(Enum):
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
def __sub__(self, other):
return self.value - other.value
def part1_type(hand):
cards = Counter(hand)
if max(cards.values()) == 5:
return HandType.FIVE_OF_A_KIND
first, second = cards.most_common(2)
first = first[1]
second = second[1]
if first == 4:
return HandType.FOUR_OF_A_KIND
elif first == 3 and second == 2:
return HandType.FULL_HOUSE
elif first == 3:
return HandType.THREE_OF_A_KIND
elif first == 2 and second == 2:
return HandType.TWO_PAIRS
elif first == 2:
return HandType.PAIR
else:
return HandType.HIGH_CARD
def part2_type(hand):
cards = Counter(hand)
jokers = cards["J"]
if jokers == 0:
return part1_type(hand)
if jokers == 5:
return HandType.FIVE_OF_A_KIND
first, second = cards.most_common(2)
if first[0] == "J" or second[0] == "J":
value = first[1] + second[1]
if value == 5:
return HandType.FIVE_OF_A_KIND
elif value == 4:
return HandType.FOUR_OF_A_KIND
elif value == 3:
return HandType.THREE_OF_A_KIND
elif value == 2:
return HandType.PAIR
a = first[1]
b = second[1]
if first[0] != "J":
a += jokers
elif second[0] != "J":
b += jokers
first, second = max(a, b), min(a, b)
if first == 4:
return HandType.FOUR_OF_A_KIND
elif first == 3 and second == 2:
return HandType.FULL_HOUSE
elif first == 3:
return HandType.THREE_OF_A_KIND
elif first == 2 and second == 2:
return HandType.TWO_PAIRS
elif first == 2:
return HandType.PAIR
else:
return HandType.HIGH_CARD
def hand_comparator(hand1, hand2, mapping, hand_type_fn):
hand1_type = hand_type_fn(hand1)
hand2_type = hand_type_fn(hand2)
if hand1_type != hand2_type:
return hand1_type - hand2_type
for card1, card2 in zip(hand1, hand2):
if card1 == card2:
continue
return mapping[card1] - mapping[card2]
def total_winnings(input, mapping, hand_type_fn):
hands = [
(hand, int(bid)) for line in input.splitlines() for hand, bid in [line.split()]
]
hands.sort(
key=cmp_to_key(lambda x, y: hand_comparator(x[0], y[0], mapping, hand_type_fn))
)
answer = 0
for i, (_, bid) in enumerate(hands):
answer += bid * (i + 1)
return answer
def part1(input):
mapping = {
"2": 2,
"3": 3,
"4": 4,
"5": 5,
"6": 6,
"7": 7,
"8": 8,
"9": 9,
"T": 10,
"J": 11,
"Q": 12,
"K": 13,
"A": 14,
}
return total_winnings(input, mapping, part1_type)
def part2(input):
mapping = {
"J": 1,
"2": 2,
"3": 3,
"4": 4,
"5": 5,
"6": 6,
"7": 7,
"8": 8,
"9": 9,
"T": 10,
"Q": 11,
"K": 12,
"A": 13,
}
return total_winnings(input, mapping, part2_type)