diff options
Diffstat (limited to '2023/go/internal/day_03')
| -rw-r--r-- | 2023/go/internal/day_03/part_01/part_01.go | 123 | ||||
| -rw-r--r-- | 2023/go/internal/day_03/part_01/part_01_test.go | 78 |
2 files changed, 201 insertions, 0 deletions
diff --git a/2023/go/internal/day_03/part_01/part_01.go b/2023/go/internal/day_03/part_01/part_01.go new file mode 100644 index 0000000..49837b3 --- /dev/null +++ b/2023/go/internal/day_03/part_01/part_01.go @@ -0,0 +1,123 @@ +package part_01 + +/** + * TRIED: + * 530923 + */ + +import ( + "os" + "strconv" + "strings" +) + +const USE_SAMPLE = true + +func Solve() { + var content []byte + if USE_SAMPLE { + content, _ = os.ReadFile("../_input/day_03_part_01_sample.txt") + } else { + content, _ = os.ReadFile("../_input/day_03.txt") + } + lines := strings.Split(string(content), "\n") + + validNumbers := walkLines(lines) + + answer := 0 + for _, number := range validNumbers { + answer += number + } + + println(answer) +} + +func walkLines(lines []string) []int { + var validNumbers []int + + for y := 0; y < len(lines); y++ { + line := lines[y] + + if line == "" || line == "\n" { + continue + } + + // Counts as a symbol... + filteredLine := strings.ReplaceAll(line, "\r", "") + + previousWasNumber := false + number := "" + for x := 0; x < len(filteredLine); x++ { + char := filteredLine[x] + + _, err := strconv.Atoi(string(char)) + isNumeric := err == nil + + if isNumeric { + previousWasNumber = true + number += string(char) + continue + } + + if !previousWasNumber { + continue + } + + isValid := checkValidity(lines, x, y, len(number)) + if isValid { + num, _ := strconv.Atoi(number) + validNumbers = append(validNumbers, num) + } + + println(number) + + previousWasNumber = false + number = "" + } + } + + return validNumbers +} + +// N = number +// k = numOfDigits + 1 +// (x-k,y-1) (x-1,y-1) ( x ,y-1) +// (x-k, y ) N ( x , y ) +// (x-k,y+1) (x-1,y+1) ( x ,y+1) +func checkValidity(lines []string, x int, y int, numOfDigits int) bool { + + for i := max(y-1, 0); i <= y+1; i++ { + + var debugLine string + + for j := max(x-(numOfDigits+1), 0); j <= x; j++ { + + if lineExists := len(lines) > i; !lineExists { + continue + } + + if charExists := len(lines[i]) > j; !charExists { + continue + } + + char := rune(lines[i][j]) + debugLine += string(char) + + if char == '.' { + continue + } + + _, err := strconv.Atoi(string(char)) + isNumeric := err == nil + if isNumeric { + continue + } + + debugLine = "" //nolint:ineffassign // Only used for debugging and needs to be reset + + return true + } + } + + return false +} diff --git a/2023/go/internal/day_03/part_01/part_01_test.go b/2023/go/internal/day_03/part_01/part_01_test.go new file mode 100644 index 0000000..a077fbd --- /dev/null +++ b/2023/go/internal/day_03/part_01/part_01_test.go @@ -0,0 +1,78 @@ +package part_01 + +import ( + "os" + "strings" + "testing" +) + +func TestWalkLines(t *testing.T) { + lines := getSampleLines() + expected := 4361 + + validNumbers := walkLines(lines) + + actual := 0 + for _, number := range validNumbers { + actual += number + } + + if actual != expected { + t.Errorf("Expected answer to be %d, got %d", expected, actual) + } +} + +func TestCheckValidity(t *testing.T) { + lines := getSampleLines() + + tests := []struct { + x int + y int + length int + expected bool + }{ + {3, 0, 3, true}, // 467 + {8, 0, 3, false}, // 114 + {9, 0, 1, false}, // 3 - Added to check for '\r' counting as a symbol + {4, 2, 2, true}, // 35 + {9, 2, 3, true}, // 633 + {9, 3, 1, false}, // 3 - Added to check if number continues to next line + {3, 4, 3, true}, // 617 + {9, 5, 2, false}, // 58 + {5, 6, 3, true}, // 592 + {9, 7, 3, true}, // 775 + {4, 9, 3, true}, // 664 + {8, 9, 3, true}, // 598 + } + + for _, test := range tests { + actual := checkValidity(lines, test.x, test.y, test.length) + + if actual != test.expected { + t.Errorf("Expected %d, %d, %d to be %t, got %t", test.x, test.y, test.length, test.expected, actual) + } + } +} + +func getSampleLines() []string { + contents, err := os.ReadFile("../../../../_input/day_03_part_01_sample.txt") + if err != nil { + panic(err) + } + + lines := strings.Split(string(contents), "\n") + + var filteredLines []string + for _, line := range lines { + if line == "" || line == "\n" { + continue + } + + // Counts as a symbol... + filteredLine := strings.ReplaceAll(line, "\r", "") + + filteredLines = append(filteredLines, filteredLine) + } + + return filteredLines +} |
