Merge pull request #8 from StevanFreeborn/stevanfreeborn/feat/implement-file-iterator

feat: implement method for reading file line at a time
This commit is contained in:
Stevan Freeborn
2025-12-06 12:31:37 -06:00
committed by GitHub
4 changed files with 80 additions and 9 deletions
+2 -2
View File
@@ -7,7 +7,7 @@ import (
) )
func SolvePartOne(filePath string) int { func SolvePartOne(filePath string) int {
lines := file.ReadLines(filePath) lines := file.ReadAllLines(filePath)
dial := dial.New() dial := dial.New()
total := 0 total := 0
@@ -28,7 +28,7 @@ func SolvePartOne(filePath string) int {
} }
func SolvePartTwo(filePath string) int { func SolvePartTwo(filePath string) int {
lines := file.ReadLines(filePath) lines := file.ReadAllLines(filePath)
dial := dial.New() dial := dial.New()
for _, line := range lines { for _, line := range lines {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
) )
func Solve(filePath string, numOfCells int) int64 { func Solve(filePath string, numOfCells int) int64 {
input := file.ReadLines(filePath) input := file.ReadAllLines(filePath)
total := int64(0) total := int64(0)
for _, line := range input { for _, line := range input {
+23 -4
View File
@@ -3,13 +3,32 @@ package file
import ( import (
"bufio" "bufio"
"iter"
"os" "os"
) )
// TODO: Implement a StreamLines method func ReadLines(filePath string) iter.Seq[string] {
// in the file package return func(yield func(string) bool) {
file, err := os.Open(filePath)
func ReadLines(filePath string) []string { if err != nil {
yield("")
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if !yield(scanner.Text()) {
return
}
}
}
}
func ReadAllLines(filePath string) []string {
lines := []string{} lines := []string{}
file, openErr := os.Open(filePath) file, openErr := os.Open(filePath)
@@ -20,7 +39,7 @@ func ReadLines(filePath string) []string {
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
for hasLine := scanner.Scan(); hasLine; hasLine = scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
lines = append(lines, line) lines = append(lines, line)
} }
+54 -2
View File
@@ -7,13 +7,13 @@ import (
"github.com/StevanFreeborn/advent-of-code-2025/internal/file" "github.com/StevanFreeborn/advent-of-code-2025/internal/file"
) )
func TestReadLines(t *testing.T) { func TestAllReadLines(t *testing.T) {
expectedLines := []string{ expectedLines := []string{
"hello", "hello",
"world", "world",
} }
result := file.ReadLines("test.txt") result := file.ReadAllLines("test.txt")
if slices.Equal(result, expectedLines) == false { if slices.Equal(result, expectedLines) == false {
t.Errorf("got %s but expected %s", result, expectedLines) t.Errorf("got %s but expected %s", result, expectedLines)
@@ -29,3 +29,55 @@ func TestReadAllText(t *testing.T) {
t.Errorf("got %q but expected %q", result, expectedText) t.Errorf("got %q but expected %q", result, expectedText)
} }
} }
func TestReadLines(t *testing.T) {
t.Run("it should return an empty line if the file does not exist", func(t *testing.T) {
expectedLines := []string{""}
lines := []string{}
for line := range file.ReadLines("non-existent-file.txt") {
lines = append(lines, line)
}
if slices.Equal(lines, expectedLines) == false {
t.Errorf("got %s but expected %s", lines, expectedLines)
}
})
t.Run("it should read all lines from the file", func(t *testing.T) {
expectedLines := []string{
"hello",
"world",
}
lines := []string{}
for line := range file.ReadLines("test.txt") {
lines = append(lines, line)
}
if slices.Equal(lines, expectedLines) == false {
t.Errorf("got %s but expected %s", lines, expectedLines)
}
})
t.Run("it should stop reading lines when iteration is stopped", func(t *testing.T) {
expectedLines := []string{
"hello",
}
lines := []string{}
for line := range file.ReadLines("test.txt") {
if len(lines) >= 1 {
break
}
lines = append(lines, line)
}
if slices.Equal(lines, expectedLines) == false {
t.Errorf("got %s but expected %s", lines, expectedLines)
}
})
}