diff options
Diffstat (limited to 'aoc')
| -rw-r--r-- | aoc/aoc_suite_test.go | 13 | ||||
| -rw-r--r-- | aoc/day.go | 19 | ||||
| -rw-r--r-- | aoc/inputters.go | 42 | ||||
| -rw-r--r-- | aoc/inputters_test.go | 53 | ||||
| -rw-r--r-- | aoc/scanner.go | 15 |
5 files changed, 142 insertions, 0 deletions
diff --git a/aoc/aoc_suite_test.go b/aoc/aoc_suite_test.go new file mode 100644 index 0000000..6e3b38b --- /dev/null +++ b/aoc/aoc_suite_test.go @@ -0,0 +1,13 @@ +package aoc_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestAoc(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Aoc Suite") +} diff --git a/aoc/day.go b/aoc/day.go new file mode 100644 index 0000000..7505223 --- /dev/null +++ b/aoc/day.go @@ -0,0 +1,19 @@ +package aoc + +import ( + "bufio" + "context" +) + +type Reader[T any] interface { + Read(ctx context.Context, scanner *bufio.Scanner) (T, error) +} + +type Solver[T any, R any] interface { + Solve(ctx context.Context, data T) (R, error) +} + +func RunDay[T any, R any](ctx context.Context, in Reader[T], solvers ...Solver[T, R]) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() +} diff --git a/aoc/inputters.go b/aoc/inputters.go new file mode 100644 index 0000000..f677177 --- /dev/null +++ b/aoc/inputters.go @@ -0,0 +1,42 @@ +package aoc + +import ( + "bufio" + "context" + "strconv" +) + +// Read all lines into type T +type ReadLines[T any] func(lines []string) (T, error) + +func (l ReadLines[T]) Read(ctx context.Context, scanner *bufio.Scanner) (T, error) { + lines := []string{} + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + return l(lines) +} + +// Read line by line into type T, collect in []T +type ReadByLine[T any] func(line string) (T, error) + +func (l ReadByLine[T]) Read(ctx context.Context, scanner *bufio.Scanner) ([]T, error) { + lines := []T{} + for scanner.Scan() { + if t, err := l(scanner.Text()); err == nil { + lines = append(lines, t) + } else { + return nil, err + } + } + return lines, nil +} + +// Read lines into ints +var ReadInts = ReadByLine[int](func(line string) (int, error) { + if i, err := strconv.Atoi(line); err != nil { + return 0, err + } else { + return i, nil + } +}) diff --git a/aoc/inputters_test.go b/aoc/inputters_test.go new file mode 100644 index 0000000..2230b1e --- /dev/null +++ b/aoc/inputters_test.go @@ -0,0 +1,53 @@ +package aoc_test + +import ( + "bufio" + "context" + "strconv" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "mvinkio.online/aoc/aoc" +) + +func newScanner(input string) *bufio.Scanner { + return bufio.NewScanner(strings.NewReader(input)) +} + +var _ = Describe("Inputters", func() { + Describe("Bylines Inputter", func() { + in := aoc.ReadByLine[int](func(line string) (int, error) { + if i, err := strconv.Atoi(line); err != nil { + return 0, err + } else { + return i, nil + } + }) + It("should map each line in the input to the expected type", func() { + data, err := in.Read(context.TODO(), newScanner("1\n1\n8\n3\n5\n8")) + Expect(err).To(BeNil()) + Expect(data).To(Equal([]int{1, 1, 8, 3, 5, 8})) + }) + }) + + Describe("Lines Inputter", func() { + in := aoc.ReadLines[[]int](func(lines []string) ([]int, error) { + ints := make([]int, len(lines)) + for i, l := range lines { + t, err := strconv.Atoi(l) + if err != nil { + return nil, err + } + ints[i] = t + } + return ints, nil + }) + It("Should correct map to type given all lines", func() { + data, err := in.Read(context.TODO(), newScanner("1\n1\n8\n3\n5\n8")) + Expect(err).To(BeNil()) + Expect(data).To(Equal([]int{1, 1, 8, 3, 5, 8})) + }) + }) +}) diff --git a/aoc/scanner.go b/aoc/scanner.go new file mode 100644 index 0000000..733f49a --- /dev/null +++ b/aoc/scanner.go @@ -0,0 +1,15 @@ +package aoc + +import ( + "bufio" + "log" + "os" +) + +func NewScannerFromFile(filename string) *bufio.Scanner { + f, err := os.Open(filename) + if err != nil { + log.Panic(err) + } + return bufio.NewScanner(f) +} |
