]> fbox.kageds.com Git - adventofcode.git/blob - 2023/go/day07/day07.go
day07
[adventofcode.git] / 2023 / go / day07 / day07.go
1 package day07
2
3 import (
4 _ "fmt"
5 "strings"
6 "sort"
7 "adventofcode2023/utils"
8
9 )
10 type Card int
11
12 const (
13 _ Card = 1 + iota
14 Two
15 Three
16 Four
17 Five
18 Six
19 Seven
20 Eight
21 Nine
22 Ten
23 Jack
24 Queen
25 King
26 Ace
27 )
28
29 type Card2 int
30 const (
31 _ Card2 = iota
32 Joker
33 Two2
34 Three2
35 Four2
36 Five2
37 Six2
38 Seven2
39 Eight2
40 Nine2
41 Ten2
42 Queen2
43 King2
44 Ace2
45 )
46
47 type HandType int
48
49 const (
50 _ HandType = iota
51 HighCard
52 OnePair
53 TwoPair
54 ThreeKind
55 FullHouse
56 FourKind
57 FiveKind
58 )
59
60 type Hand struct {
61 cards [5]Card
62 bid int
63 rank int
64 handType HandType
65 }
66
67 type Hand2 struct {
68 cards [5]Card2
69 bid int
70 rank int
71 handType HandType
72 }
73
74 func Part1(input string) int {
75 total := 0
76 hands := parseInput(1, input)
77 sort.Slice(hands, func(i, j int) bool {
78 if hands[i].handType == hands[j].handType {
79 for k:=0;k<5;k++{
80 if hands[i].cards[k] == hands[j].cards[k] {
81 continue
82 }
83 return hands[i].cards[k] < hands[j].cards[k]
84 }
85 }
86 return hands[i].handType < hands[j].handType
87 })
88 for i,hand := range hands {
89 total += (i+1) * hand.bid
90 }
91 return total
92 }
93
94 func Part2(input string) int {
95 total := 0
96 hands := parseInput(2, input)
97 sort.Slice(hands, func(i, j int) bool {
98 if hands[i].handType == hands[j].handType {
99 for k:=0;k<5;k++{
100 if hands[i].cards[k] == hands[j].cards[k] {
101 continue
102 }
103 if hands[i].cards[k] == Jack {return true}
104 if hands[j].cards[k] == Jack {return false}
105 return hands[i].cards[k] < hands[j].cards[k]
106 }
107 }
108 return hands[i].handType < hands[j].handType
109 })
110 for i,hand := range hands {
111 total += (i+1) * hand.bid
112 }
113 return total
114 }
115
116 func parseInput(part int, input string) ([]Hand) {
117 var hand Hand
118 var hands []Hand
119 lines := strings.Split(input, "\n")
120 for _, line := range lines {
121 tokens := strings.Fields(line)
122 hand.bid = utils.MustAtoi(tokens[1])
123 for i, j := range tokens[0] {
124 hand.cards[i] = toCard(j)
125 }
126 hand.handType = toHandType(part, hand.cards)
127 hands = append(hands, hand)
128 }
129 return hands
130 }
131
132 func toCard(j rune) Card {
133 switch j {
134 case '2':
135 return Two
136 case '3':
137 return Three
138 case '4':
139 return Four
140 case '5':
141 return Five
142 case '6':
143 return Six
144 case '7':
145 return Seven
146 case '8':
147 return Eight
148 case '9':
149 return Nine
150 case 'T':
151 return Ten
152 case 'J':
153 return Jack
154 case 'Q':
155 return Queen
156 case 'K':
157 return King
158 case 'A':
159 return Ace
160 }
161 return -1
162 }
163
164 func toHandType(part int, cards [5]Card) HandType {
165 jokers := 0
166 handType := HighCard
167 cardMap := make(map[Card]int)
168 for _, card := range cards {
169 if part == 2 && card == Jack {
170 jokers++
171 } else {
172 if _, ok := cardMap[card]; ok {
173 cardMap[card]++
174 } else {
175 cardMap[card] = 1
176 }
177 }
178 }
179 cardSorted := ToSortedSlice(cardMap)
180 if part == 2 && jokers == 5 { return FiveKind}
181 if part == 2 && jokers > 0 {
182 cardSorted[0].Value = cardSorted[0].Value + jokers
183 }
184 if cardSorted[0].Value == 5 { handType = FiveKind}
185 if cardSorted[0].Value == 4 { handType = FourKind}
186 if cardSorted[0].Value == 3 {
187 if cardSorted[1].Value == 2 {handType = FullHouse}
188 if cardSorted[1].Value == 1 {handType = ThreeKind}
189 }
190 if cardSorted[0].Value == 2 {
191 if cardSorted[1].Value == 2 {handType = TwoPair}
192 if cardSorted[1].Value == 1 {handType = OnePair}
193 }
194 return handType
195 }
196
197 //func toHandType(part int, cards [5]Card) HandType {
198 // cardMap := make(map[Card]int)
199 // for _, card := range cards {
200 // if _, ok := cardMap[card]; ok {
201 // cardMap[card]++
202 // } else {
203 // cardMap[card] = 1
204 // }
205 // }
206 // if part == 2 {
207 // switch cardMap[Jack] {
208 // case 5:
209 // return FiveKind
210 // case 4:
211 // return FiveKind
212 // case 3:
213 // if len(cardMap) == 2 {return FiveKind}
214 // return FourKind
215 // case 2:
216 // switch len(cardMap) {
217 // case 2:
218 // return FiveKind
219 // case 3:
220 // return FourKind
221 // case 4:
222 // return ThreeKind
223 //
224 // }
225 // case 1:
226 // switch len(cardMap) {
227 // case 2:
228 // return FiveKind
229 // case 3:
230 // max := utils.MapFindMax(cardMap)
231 // if max == 3 {return FourKind}
232 // if max == 2 {return FullHouse}
233 // case 4:
234 // return ThreeKind
235 // case 5:
236 // return OnePair
237 //
238 // }
239 // }
240 // }
241 // switch len(cardMap) {
242 // case 5:
243 // return HighCard
244 // case 4:
245 // return OnePair
246 // case 3:
247 // for _, count := range cardMap {
248 // if count == 3 {
249 // return ThreeKind
250 // }
251 // }
252 // return TwoPair
253 // case 2:
254 // for _, count := range cardMap {
255 // if count == 4 {
256 // return FourKind
257 // }
258 // }
259 // return FullHouse
260 // case 1:
261 // return FiveKind
262 // }
263 // return -1
264 //}
265
266 // KeyValue is a struct to hold key-value pairs
267 type KeyValue struct {
268 Key Card
269 Value int
270 }
271
272 func ToSortedSlice(myMap map[Card]int) []KeyValue {
273
274 var keyValuePairs []KeyValue
275 for key, value := range myMap {
276 keyValuePairs = append(keyValuePairs, KeyValue{key, value})
277 }
278
279 // Sort the slice by values
280 sort.Slice(keyValuePairs, func(i, j int) bool {
281 if keyValuePairs[i].Value == keyValuePairs[j].Value { return keyValuePairs[i].Key > keyValuePairs[j].Key }
282 return keyValuePairs[i].Value > keyValuePairs[j].Value
283 })
284
285 // Create a new map with sorted key-value pairs
286 //sortedMap := make(map[Card]int)
287 //for _, kv := range keyValuePairs {
288 // sortedMap[kv.Key] = kv.Value
289 //}
290 return keyValuePairs
291 }