diff options
| author | DJ O'Leary <dijitol@proton.me> | 2025-03-03 00:56:33 +0100 |
|---|---|---|
| committer | DJ O'Leary <dijitol@proton.me> | 2025-03-03 00:56:33 +0100 |
| commit | e24effa8fd3574e9d396be0e1a47f101c27c0a60 (patch) | |
| tree | 793896d20384facd10d925e09f8f0dd89c930cce /2023/Go/internal/day_04/part_01 | |
perf: Merge Advent of Code year specific repos
Diffstat (limited to '2023/Go/internal/day_04/part_01')
| -rw-r--r-- | 2023/Go/internal/day_04/part_01/part_01.go | 130 | ||||
| -rw-r--r-- | 2023/Go/internal/day_04/part_01/part_01_test.go | 48 |
2 files changed, 178 insertions, 0 deletions
diff --git a/2023/Go/internal/day_04/part_01/part_01.go b/2023/Go/internal/day_04/part_01/part_01.go new file mode 100644 index 0000000..1a215b1 --- /dev/null +++ b/2023/Go/internal/day_04/part_01/part_01.go @@ -0,0 +1,130 @@ +package part_01 + +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_01_sample.txt") + } else { + contents, _ = os.ReadFile("../_input/day_04.txt") + } + + lines := strings.Split(string(contents), "\n") + + answer := 0 + for _, line := range lines { + if line == "" || line == "\n" { + continue + } + + card := parseCardLine(line) + score := tallyScore(card) + + answer += score + } + + 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 tallyScore(card Card) int { + score := 0 + for _, winningNumber := range card.winningNumbers { + if slices.Contains(card.haveNumbers, winningNumber) { + if score == 0 { + score = 1 + } else { + score *= 2 + } + } + } + + return score +} diff --git a/2023/Go/internal/day_04/part_01/part_01_test.go b/2023/Go/internal/day_04/part_01/part_01_test.go new file mode 100644 index 0000000..f6f1a83 --- /dev/null +++ b/2023/Go/internal/day_04/part_01/part_01_test.go @@ -0,0 +1,48 @@ +package part_01 + +import ( + "testing" +) + +func TestParseCardLine(t *testing.T) { + input := "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53" + expected := Card{1, []int{41, 48, 83, 86, 17}, []int{83, 86, 6, 31, 17, 9, 48, 53}} + + actual := parseCardLine(input) + + if actual.id != expected.id { + t.Errorf("ERROR: ID %d does not match expected %d", actual.id, expected.id) + } + + if len(actual.winningNumbers) != len(expected.winningNumbers) { + t.Errorf("ERROR: len(WinningNumbers) %d does not match expected %d", len(actual.winningNumbers), len(expected.winningNumbers)) + } + + if len(actual.haveNumbers) != len(expected.haveNumbers) { + t.Errorf("ERROR: len(HaveNumbers) %d does not match expected %d", len(actual.haveNumbers), len(expected.haveNumbers)) + } + + for i, num := range actual.winningNumbers { + if num != expected.winningNumbers[i] { + t.Errorf("ERROR: WinningNumber %d does not match expected %d", num, expected.winningNumbers[i]) + } + } + + for i, num := range actual.haveNumbers { + if num != expected.haveNumbers[i] { + t.Errorf("ERROR: HaveNumber %d does not match expected %d", num, expected.haveNumbers[i]) + } + } + +} + +func TestTallyScore(t *testing.T) { + card := Card{1, []int{41, 48, 83, 86, 17}, []int{83, 86, 6, 31, 17, 9, 48, 53}} + expected := 8 + + actual := tallyScore(card) + + if actual != expected { + t.Errorf("ERROR: Score %d does not match expected %d", actual, expected) + } +} |
