@@ -2,8 +2,8 @@ package main
22
33import (
44 _ "embed"
5- "fmt"
65 "os"
6+ "slices"
77 "strings"
88)
99
@@ -13,56 +13,121 @@ var input string
1313//go:embed input_test.txt
1414var inputTest string
1515
16+ type Hand struct {
17+ cards [5 ]int
18+ bid int
19+ }
20+
21+ var hands []Hand
22+
1623func main () {
1724 // Check argv if we use test input or not
1825 if len (os .Args ) > 1 && os .Args [1 ] == "test" {
1926 input = inputTest
2027 }
2128
22- answer := doPartOne (input )
29+ parseInput (input )
30+
31+ answer := doPartOne ()
2332 println (answer )
2433
25- answer = doPartTwo (input )
34+ answer = doPartTwo ()
2635 println (answer )
2736}
2837
29- type Hands []Hand
30- type Hand struct {
31- hand []int
32- bid int
33- }
34- type Score struct {
35- hand []int
36- strength int
38+ func parseInput (input string ) {
39+ lines := strings .Split (strings .TrimSpace (input ), "\n " )
40+ hands = make ([]Hand , len (lines ))
41+
42+ for i , line := range lines {
43+ spaceIdx := strings .Index (line , " " )
44+
45+ // Parse hand
46+ var h Hand
47+ for j := 0 ; j < 5 ; j ++ {
48+ h .cards [j ] = cardValue (line [j ])
49+ }
50+
51+ // Parse bid
52+ bid := 0
53+ for j := spaceIdx + 1 ; j < len (line ); j ++ {
54+ bid = bid * 10 + int (line [j ]- '0' )
55+ }
56+ h .bid = bid
57+
58+ hands [i ] = h
59+ }
3760}
3861
39- var (
40- handscores = []Score {
41- {[]int {5 }, 10 }, {[]int {1 , 4 }, 9 }, {[]int {2 , 3 }, 8 }, {[]int {1 , 1 , 3 }, 7 },
42- {[]int {1 , 2 , 2 }, 6 }, {[]int {1 , 1 , 1 , 2 }, 5 }, {[]int {1 , 1 , 1 , 1 , 1 }, 4 },
62+ func cardValue (c byte ) int {
63+ switch c {
64+ case 'A' :
65+ return 14
66+ case 'K' :
67+ return 13
68+ case 'Q' :
69+ return 12
70+ case 'J' :
71+ return 11
72+ case 'T' :
73+ return 10
74+ default :
75+ return int (c - '0' )
4376 }
77+ }
4478
45- cardscore = map [rune ]int {
46- '1' : 1 , '2' : 2 , '3' : 3 , '4' : 4 , '5' : 5 , '6' : 6 , '7' : 7 ,
47- '8' : 8 , '9' : 9 , 'T' : 10 , 'J' : 11 , 'Q' : 12 , 'K' : 13 , 'A' : 14 ,
79+ // Calculate hand strength from card counts
80+ // Five of a kind: 6, Four of a kind: 5, Full house: 4, Three of a kind: 3, Two pair: 2, One pair: 1, High card: 0
81+ func handStrength (counts [5 ]int ) int {
82+ slices .Sort (counts [:])
83+ // counts is now sorted, highest count at the end
84+ switch counts [4 ] {
85+ case 5 :
86+ return 6 // Five of a kind
87+ case 4 :
88+ return 5 // Four of a kind
89+ case 3 :
90+ if counts [3 ] == 2 {
91+ return 4 // Full house
92+ }
93+ return 3 // Three of a kind
94+ case 2 :
95+ if counts [3 ] == 2 {
96+ return 2 // Two pair
97+ }
98+ return 1 // One pair
99+ default :
100+ return 0 // High card
48101 }
49- )
102+ }
50103
51- func getHands (input string , p2 bool ) Hands {
52- var hands Hands
53- for _ , line := range strings .Split (strings .TrimSpace (input ), "\n " ) {
54- var H string
55- var B int
56- fmt .Sscanf (line , "%s %d" , & H , & B )
57- hand := []int {}
58- for _ , c := range H {
59- n := cardscore [c ]
60- if c == 'J' && p2 {
61- n = 1
62- }
63- hand = append (hand , n )
64- }
65- hands = append (hands , Hand {hand , B })
104+ func getHandStrength (h Hand , jokerRule bool ) int {
105+ counts := [5 ]int {}
106+ cardCounts := make (map [int ]int )
107+
108+ for _ , card := range h .cards {
109+ cardCounts [card ]++
110+ }
111+
112+ // Handle jokers (value 11 in part 1, converted to 1 in part 2)
113+ jokers := 0
114+ if jokerRule {
115+ jokers = cardCounts [1 ]
116+ delete (cardCounts , 1 )
117+ }
118+
119+ // Fill counts array
120+ i := 0
121+ for _ , count := range cardCounts {
122+ counts [i ] = count
123+ i ++
124+ }
125+
126+ // Add jokers to the highest count
127+ if jokers > 0 {
128+ slices .Sort (counts [:])
129+ counts [4 ] += jokers
66130 }
67- return hands
131+
132+ return handStrength (counts )
68133}
0 commit comments