diff --git a/day4/dayFour.go b/day4/dayFour.go new file mode 100644 index 0000000..3cb3ba6 --- /dev/null +++ b/day4/dayFour.go @@ -0,0 +1,110 @@ +package day4 + +import ( + "fmt" + "os" + "strconv" + "strings" +) + +func Run() int { + fmt.Println("in day 4") + cards := ReadAllCards() + result := 0 + + for _, card := range cards { + fmt.Printf("> checking card %+v with points %d", card, card.GetPoints()) + result += card.GetPoints() + } + + return result +} + +type Card struct { + Title int + WinningNums []int + OwnNums []int +} + +func ReadAllCards() []Card { + filename := "day4/example" + bytes, err := os.ReadFile(filename) + if err != nil { + panic(fmt.Sprintf("can't read file %s", filename)) + } + text := string(bytes) + lines := strings.Split(text, "\n") + result := make([]Card, len(lines)) + + for _, line := range lines { + if line == "" { + continue + } + result = append(result, ReadCard(line)) + } + + return result +} + +// read line like 'Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53' +func ReadCard(line string) Card { + result := Card{} + extractingTitle := strings.Split(line, ":") + title := extractingTitle[0] + numberPart := extractingTitle[1] + + titleNumStr := strings.Split(title, " ")[1] + titleNum, err := strconv.Atoi(titleNumStr) + if err != nil { + panic(fmt.Sprintf("error extracting card title: %s, %s", line, titleNumStr)) + } + result.Title = titleNum + + extractingNumbers := strings.Split(numberPart, "|") + for _, winningNumStr := range strings.Split( extractingNumbers[0], " " ) { + winningNumStr = strings.TrimSpace(winningNumStr) + if winningNumStr == "" { + continue + } + winningNum, err := strconv.Atoi(winningNumStr) + if err != nil { + panic(fmt.Sprintf("error extracting winning card num: %s from '%s'", line, winningNumStr)) + } + result.WinningNums = append(result.WinningNums, winningNum) + } + for _, ownNumStr := range strings.Split( extractingNumbers[1], " " ) { + ownNumStr = strings.TrimSpace(ownNumStr) + if ownNumStr == "" { + continue + } + ownNum, err := strconv.Atoi(ownNumStr) + if err != nil { + panic(fmt.Sprintf("error extracting own card num: %s, %s", line, ownNumStr)) + } + result.OwnNums = append(result.OwnNums, ownNum) + } + + return result +} + +func (c *Card)GetPoints() int { + winningSet := make(map[int]any) + for _, winNum := range c.WinningNums { + winningSet[winNum] = struct{}{} + } + + result := 0 + hasMatch := false + for _, ownNum := range c.OwnNums { + _, isWinning := winningSet[ownNum] + if isWinning { + if !hasMatch { + result = 1 + hasMatch = true + } else { + result *= 2 + } + } + } + return result +} diff --git a/day4/example b/day4/example new file mode 100644 index 0000000..9bdb874 --- /dev/null +++ b/day4/example @@ -0,0 +1,6 @@ +Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 +Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 +Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 +Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 +Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 +Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11 diff --git a/main.go b/main.go index 7a45a15..255b2f2 100644 --- a/main.go +++ b/main.go @@ -3,11 +3,11 @@ package main import ( "log" - "sunshine.industries/aoc2023/day3" + "sunshine.industries/aoc2023/day4" ) func main() { log.Print("> starting run:") - result := day3.Run() - log.Printf("day3 result: %d", result) + result := day4.Run() + log.Printf("day4 result: %d\n****\n", result) }