summaryrefslogtreecommitdiff
path: root/aoc
diff options
context:
space:
mode:
Diffstat (limited to 'aoc')
-rw-r--r--aoc/aoc_suite_test.go13
-rw-r--r--aoc/day.go19
-rw-r--r--aoc/inputters.go42
-rw-r--r--aoc/inputters_test.go53
-rw-r--r--aoc/scanner.go15
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)
+}