summaryrefslogtreecommitdiff
path: root/2023/Go/internal/day_04/part_01
diff options
context:
space:
mode:
Diffstat (limited to '2023/Go/internal/day_04/part_01')
-rw-r--r--2023/Go/internal/day_04/part_01/part_01.go130
-rw-r--r--2023/Go/internal/day_04/part_01/part_01_test.go48
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)
+ }
+}