github.com/agrigoryan/aoc_2023_go@v0.0.0-20231216221323-4ace361ec685/day7/d7p2.go (about) 1 package day7 2 3 import ( 4 "fmt" 5 "log" 6 "slices" 7 "strconv" 8 "strings" 9 ) 10 11 func d7p2(input string) int { 12 lines := strings.Split(input, "\n") 13 hands := []*hand{} 14 15 for _, line := range lines { 16 var h = parseHand2(line) 17 hands = append(hands, h) 18 } 19 20 slices.SortFunc(hands, func(a, b *hand) int { 21 if a.rank != b.rank { 22 return b.rank - a.rank 23 } 24 for i := 0; i < len(a.cards); i++ { 25 if a.cards[i] != b.cards[i] { 26 return b.cards[i] - a.cards[i] 27 } 28 } 29 return 0 30 }) 31 32 sum := 0 33 for i, h := range hands { 34 sum += h.bid * (i + 1) 35 } 36 37 fmt.Println(sum) 38 return sum 39 } 40 41 func parseHand2(str string) *hand { 42 h := &hand{} 43 numJokers := 0 44 for i, r := range str[:5] { 45 card := ctoi[r] 46 h.cards[i] = card 47 h.counts[card] += 1 48 if card == cJ { 49 numJokers += 1 50 } 51 if bid, err := strconv.Atoi(str[6:]); err != nil { 52 log.Fatal("error parsing bid", err) 53 } else { 54 h.bid = bid 55 } 56 } 57 58 h.resolveRank2() 59 return h 60 } 61 62 func (h *hand) resolveRank2() { 63 sortedCounts := make([]int, len(h.counts)) 64 copy(sortedCounts, h.counts[:]) 65 numJoker := sortedCounts[cJ] 66 if numJoker > 0 { 67 maxCard := 0 68 maxCount := 0 69 for i, c := range sortedCounts { 70 if c > maxCount && i != cJ { 71 maxCard = i 72 maxCount = c 73 } 74 } 75 sortedCounts[maxCard] += numJoker 76 sortedCounts[cJ] = 0 77 } 78 slices.SortFunc(sortedCounts, func(a, b int) int { return b - a }) 79 switch sortedCounts[0] { 80 case 5: 81 h.rank = rFiveOfAKind 82 case 4: 83 h.rank = rFourOfAKind 84 case 3: 85 if sortedCounts[1] >= 2 { 86 h.rank = rFullHouse 87 } else { 88 h.rank = rTheeOfAKind 89 } 90 case 2: 91 if sortedCounts[1] >= 2 { 92 h.rank = rTwoPairs 93 } else { 94 h.rank = rPair 95 } 96 default: 97 h.rank = rHighCard 98 } 99 }