package day7 import ( "fmt" "log" "os" "slices" "strconv" "strings" ) func Run() int { fmt.Print("hello day 7") filename := "day7/input" input := ReadFile(filename) slices.SortFunc(input, CompareHands) // log.Printf("read the input %+v\n", input) for _, hand := range input { // fmt.Printf("%+v\n", hand) fmt.Printf("%+s\t\t%d\n", hand.Cards, hand.HandType) } slices.SortFunc([]int{}, func(a int, b int) int { return 0 }) result := 0 for i, hand := range input { result += (i+1) * hand.Bid } return result } type HandType int const ( HighCard = iota OnePair TwoPair ThreeKind FullHouse FourKind FiveKind ) type Hand struct { Cards string Grouped map[rune]int HandType HandType Bid int } // cmp(a, b) should return a negative number when a < b, a positive number when // a > b and zero when a == b. const values string = "J23456789TQKA" func CompareHands(a Hand, b Hand) int { if a.HandType != b.HandType { return int(a.HandType) - int(b.HandType) } return compareString(a.Cards, b.Cards) } func compareString(a string, b string) int { for i := 0; i < len(a); i++ { if a[i] == b[i] { continue } aVal := strings.IndexRune(values, rune(a[i])) bVal := strings.IndexRune(values, rune(b[i])) return aVal - bVal } return 0 } func GetHandType(groupped map[rune]int) HandType { var handType HandType jokerSize, found := groupped['J'] if !found { jokerSize = 0 } sizes := make([]int, 0, len(groupped)) for card, size := range groupped { if card != 'J' { sizes = append(sizes, size) } } slices.SortFunc(sizes, func (a, b int) int { return b - a }) var highest int if len(sizes) == 0 { highest = jokerSize } else { highest = sizes[0] + jokerSize } if highest == 5 { return FiveKind } if highest == 4 { return FourKind } other := sizes[1] if highest == 3 { if other == 2 { return FullHouse } return ThreeKind } if highest == 2 { if other == 2 { return TwoPair } return OnePair } // log.Printf("calc type for %+v.\nsizes: %+v;\n %d", groupped, sizes, handType) return handType } func ReadFile(filename string) []Hand { bytes, err := os.ReadFile(filename) if err != nil { panic(fmt.Sprintln("error reading file : ", filename)) } text := string(bytes) lines := strings.Split(text, "\n") linesLen := len(lines) result := make([]Hand, 0, linesLen) for _, line := range lines { log.Println("reading in line : ", line) if line == "" { continue } firstSplit := strings.Fields(line) cards := firstSplit[0] bidStr := firstSplit[1] bid, err := strconv.Atoi(bidStr) if err != nil { panic(fmt.Sprintln("error getting bid from : ", bidStr)) } groupped := make(map[rune]int, 0) for _, card := range cards { groupped[card] += 1 } hand := Hand{ Cards: cards, Grouped: groupped, Bid: bid, HandType: GetHandType(groupped), } result = append(result, hand) } return result }