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) 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 = "23456789TJQKA" 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 sizes := make([]int, 0, len(groupped)) for _, size := range groupped { sizes = append(sizes, size) } slices.Sort(sizes) switch { case slices.Equal(sizes, []int{5}): handType = FiveKind case slices.Equal(sizes, []int{1, 4}): handType = FourKind case slices.Equal(sizes, []int{2, 3}): handType = FullHouse case slices.Equal(sizes, []int{1, 1, 3}): handType = ThreeKind case slices.Equal(sizes, []int{1, 2, 2}): handType = TwoPair case slices.Equal(sizes, []int{1, 1, 1, 2}): handType = 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 }