summaryrefslogtreecommitdiff
path: root/2023/Go/internal/day_06/part_01
diff options
context:
space:
mode:
authorDJ O'Leary <dijitol@proton.me>2025-03-03 00:56:33 +0100
committerDJ O'Leary <dijitol@proton.me>2025-03-03 00:56:33 +0100
commite24effa8fd3574e9d396be0e1a47f101c27c0a60 (patch)
tree793896d20384facd10d925e09f8f0dd89c930cce /2023/Go/internal/day_06/part_01
perf: Merge Advent of Code year specific repos
Diffstat (limited to '2023/Go/internal/day_06/part_01')
-rw-r--r--2023/Go/internal/day_06/part_01/part_01.go85
-rw-r--r--2023/Go/internal/day_06/part_01/part_01_test.go96
2 files changed, 181 insertions, 0 deletions
diff --git a/2023/Go/internal/day_06/part_01/part_01.go b/2023/Go/internal/day_06/part_01/part_01.go
new file mode 100644
index 0000000..5735924
--- /dev/null
+++ b/2023/Go/internal/day_06/part_01/part_01.go
@@ -0,0 +1,85 @@
+package part_01
+
+import (
+ "os"
+ "strconv"
+ "strings"
+)
+
+const USE_SAMPLE = false
+
+/**
+ * Tried:
+ * - 72128 (too low)
+ * - 3317888 (correct!)
+ */
+func Solve() {
+ var filePath string
+ if USE_SAMPLE {
+ filePath = "../_input/day_06_part_01_sample.txt"
+ } else {
+ filePath = "../_input/day_06.txt"
+ }
+ contents, _ := os.ReadFile(filePath)
+
+ lines := strings.Split(string(contents), "\r\n")
+
+ timeLine := lines[0]
+ times := parseTimeLine(timeLine)
+
+ distLine := lines[1]
+ distances := parseDistanceLine(distLine)
+
+ answer := calculateAnswer(times, distances)
+
+ println(answer)
+}
+
+func parseTimeLine(timeLine string) []int {
+ prefix := "Time:"
+ return parseLine(prefix, timeLine)
+}
+
+func parseDistanceLine(distLine string) []int {
+ prefix := "Distance:"
+ return parseLine(prefix, distLine)
+}
+
+func parseLine(prefix string, line string) []int {
+ withoutTitle := strings.TrimPrefix(line, prefix)
+
+ numbers := []int{}
+ for _, number := range strings.Split(withoutTitle, " ") {
+ if number == "" {
+ continue
+ }
+ numberInt, _ := strconv.Atoi(number)
+ numbers = append(numbers, numberInt)
+ }
+ return numbers
+}
+
+func calculateAnswer(times []int, distances []int) int {
+ answer := 1
+ for i, maxTime := range times {
+ recordDistance := distances[i]
+
+ var greaterThanRecord []int
+ for buttonPressedFor := 0; buttonPressedFor <= maxTime; buttonPressedFor++ {
+ distance := calculateDistance(buttonPressedFor, maxTime)
+ if distance > recordDistance {
+ greaterThanRecord = append(greaterThanRecord, distance)
+ }
+ }
+
+ if len(greaterThanRecord) > 0 {
+ answer *= len(greaterThanRecord)
+ }
+ }
+
+ return answer
+}
+
+func calculateDistance(buttonPressedFor int, maxTime int) int {
+ return buttonPressedFor * (maxTime - buttonPressedFor)
+}
diff --git a/2023/Go/internal/day_06/part_01/part_01_test.go b/2023/Go/internal/day_06/part_01/part_01_test.go
new file mode 100644
index 0000000..7af828c
--- /dev/null
+++ b/2023/Go/internal/day_06/part_01/part_01_test.go
@@ -0,0 +1,96 @@
+package part_01
+
+import "testing"
+
+func TestParseTimeLine(t *testing.T) {
+ tests := map[string]struct {
+ input string
+ expected []int
+ }{
+ "empty": {"", []int{}},
+ "sample": {"Time: 7 15 30", []int{7, 15, 30}},
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ actual := parseTimeLine(test.input)
+ if len(actual) != len(test.expected) {
+ t.Errorf("Expected %d, got %d", len(test.expected), len(actual))
+ }
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != test.expected[i] {
+ t.Errorf("Expected %d, got %d", test.expected[i], actual[i])
+ }
+ }
+ })
+ }
+}
+
+func TestParseDistLine(t *testing.T) {
+ tests := map[string]struct {
+ input string
+ expected []int
+ }{
+ "empty": {"", []int{}},
+ "sample": {"Distance: 9 40 200", []int{9, 40, 200}},
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ actual := parseDistanceLine(test.input)
+ if len(actual) != len(test.expected) {
+ t.Errorf("Expected %d, got %d", len(test.expected), len(actual))
+ }
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != test.expected[i] {
+ t.Errorf("Expected %d, got %d", test.expected[i], actual[i])
+ }
+ }
+ })
+ }
+}
+
+func TestCalculateAnswer(t *testing.T) {
+ tests := map[string]struct {
+ times []int
+ distances []int
+ expected int
+ }{
+ "sample": {[]int{7, 15, 30}, []int{9, 40, 200}, 288},
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ actual := calculateAnswer(test.times, test.distances)
+ if actual != test.expected {
+ t.Errorf("Expected %d, got %d", test.expected, actual)
+ }
+ })
+ }
+}
+
+func TestCalculateDistance(t *testing.T) {
+ tests := map[string]struct {
+ maxTime int
+ buttonPressedFor int
+ expected int
+ }{
+ "7_7": {7, 7, 0},
+ "7_6": {7, 6, 6},
+ "7_5": {7, 5, 10},
+ "7_4": {7, 4, 12},
+ "7_3": {7, 3, 12},
+ "7_2": {7, 2, 10},
+ "7_1": {7, 1, 6},
+ "7_0": {7, 0, 0},
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ actual := calculateDistance(test.buttonPressedFor, test.maxTime)
+ if actual != test.expected {
+ t.Errorf("Expected %d, got %d", test.expected, actual)
+ }
+ })
+ }
+}