diff options
| author | DJ O'Leary <dijitol@proton.me> | 2026-06-26 18:04:09 +0200 |
|---|---|---|
| committer | DJ O'Leary <dijitol@proton.me> | 2026-06-26 18:04:09 +0200 |
| commit | 6d8fb621d1e93b83786890d6d9cb6f0d8defa8ae (patch) | |
| tree | 17c90d3984c114aa023600cc5bec6f6004b02243 /go/2023/internal/day_04/part_02/part_02.go | |
| parent | ad4ea5ca4bc9f7540ee1d6a4fa2d881709dc6459 (diff) | |
refactor!: invert repo directory structure
now is language first
Diffstat (limited to 'go/2023/internal/day_04/part_02/part_02.go')
| -rw-r--r-- | go/2023/internal/day_04/part_02/part_02.go | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/go/2023/internal/day_04/part_02/part_02.go b/go/2023/internal/day_04/part_02/part_02.go new file mode 100644 index 0000000..a9e3152 --- /dev/null +++ b/go/2023/internal/day_04/part_02/part_02.go @@ -0,0 +1,142 @@ +package part_02 + +import ( + "os" + "slices" + "strconv" + "strings" +) + +const USE_SAMPLE = false + +type UnparsedCard struct { + id string + winningNumbers []string + haveNumbers []string +} + +type Card struct { + id int + winningNumbers []int + haveNumbers []int +} + +func (c UnparsedCard) parse() Card { + var card Card + + id, err := strconv.Atoi(c.id) + if err != nil { + panic(err) + } + card.id = id + + for _, number := range c.winningNumbers { + num, err := strconv.Atoi(number) + if err != nil { + panic(err) + } + card.winningNumbers = append(card.winningNumbers, num) + } + + for _, number := range c.haveNumbers { + num, err := strconv.Atoi(number) + if err != nil { + panic(err) + } + card.haveNumbers = append(card.haveNumbers, num) + } + + return card +} + +func Solve() { + var contents []byte + if USE_SAMPLE { + contents, _ = os.ReadFile("../_input/day_04_part_02_sample.txt") + } else { + contents, _ = os.ReadFile("../_input/day_04.txt") + } + + lines := strings.Split(string(contents), "\n") + + dict := map[int]Card{} + var cards []Card + for _, line := range lines { + if line == "" || line == "\n" { + continue + } + + card := parseCardLine(line) + + dict[card.id] = card + cards = append(cards, card) + } + + answer := processCards(dict, cards) + + println(answer) +} + +// "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53" +func parseCardLine(line string) Card { + var unparsedCard UnparsedCard + + filteredLine := strings.ReplaceAll(line, "\r", "") + + // "Card 1" + card_parts := strings.Split(filteredLine, ":")[0] + id_parts := strings.Split(card_parts, " ") + id := id_parts[len(id_parts)-1] + unparsedCard.id = strings.ReplaceAll(id, " ", "") + + // "41 48 83 86 17 | 83 86 6 31 17 9 48 53" + numbers := strings.Split(filteredLine, ":")[1] + + // " 41 48 83 86 17" + winningNumberString := strings.Split(numbers, "|")[0] + // ["", "41", "48", "83", "86", "17"] + winningNumbers := strings.Split(winningNumberString, " ") + for _, num := range winningNumbers { + if num == "" || num == " " { + continue + } + unparsedCard.winningNumbers = append(unparsedCard.winningNumbers, num) + } + + // " 83 86 6 31 17 9 48 53" + haveNumberString := strings.Split(numbers, "|")[1] + // ["", "83", "86", "", "6", "31", "17", "", "9", "48", "53"] + haveNumbers := strings.Split(haveNumberString, " ") + for _, num := range haveNumbers { + if num == "" || num == " " { + continue + } + unparsedCard.haveNumbers = append(unparsedCard.haveNumbers, num) + } + + return unparsedCard.parse() +} + +func processCards(dict map[int]Card, cards []Card) int { + for i := 0; i < len(cards); i++ { + card := cards[i] + matchCount := calculateNumberOfMatches(card) + for j := card.id + 1; j < (card.id + 1 + matchCount); j++ { + copyCard := dict[j] + cards = append(cards, copyCard) + } + } + + return len(cards) +} + +func calculateNumberOfMatches(card Card) int { + matchCount := 0 + for _, winningNumber := range card.winningNumbers { + if slices.Contains(card.haveNumbers, winningNumber) { + matchCount++ + } + } + + return matchCount +} |
