summaryrefslogtreecommitdiff
path: root/go/series
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-08-26 09:21:31 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-08-26 09:21:31 +0200
commit5905c68a1fbae71682ff2edea7c009ad0355e9fb (patch)
tree97c1979119448aa77e2f6f80e2ba2c16be3bf8bd /go/series
parent8caa9002f4a9ab7a95d73aca5b185ec1da1da6ac (diff)
Solve series
Diffstat (limited to 'go/series')
-rw-r--r--go/series/README.md38
-rw-r--r--go/series/asktoomuch_test.go29
-rw-r--r--go/series/first_test.go23
-rw-r--r--go/series/series.go25
-rw-r--r--go/series/series_test.go94
5 files changed, 209 insertions, 0 deletions
diff --git a/go/series/README.md b/go/series/README.md
new file mode 100644
index 0000000..6474366
--- /dev/null
+++ b/go/series/README.md
@@ -0,0 +1,38 @@
+# Series
+
+Write a program that will take a string of digits and give you all the contiguous substrings of length `n` in that string.
+
+For example, the string "49142" has the following 3-digit series:
+
+- 491
+- 914
+- 142
+
+And the following 4-digit series:
+
+- 4914
+- 9142
+
+And if you ask for a 6-digit series from a 5-digit string, you deserve
+whatever you get.
+
+Note that these series are only required to occupy *adjacent positions*
+in the input; the digits need not be *numerically consecutive*.
+
+To run the tests simply run the command `go test` in the exercise directory.
+
+If the test suite contains benchmarks, you can run these with the `-bench`
+flag:
+
+ go test -bench .
+
+For more detailed info about the Go track see the [help
+page](http://exercism.io/languages/go).
+
+## Source
+
+A subset of the Problem 8 at Project Euler [http://projecteuler.net/problem=8](http://projecteuler.net/problem=8)
+
+## Submitting Incomplete Problems
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.
+
diff --git a/go/series/asktoomuch_test.go b/go/series/asktoomuch_test.go
new file mode 100644
index 0000000..e29703a
--- /dev/null
+++ b/go/series/asktoomuch_test.go
@@ -0,0 +1,29 @@
+// +build asktoomuch
+
+package slice
+
+import "testing"
+
+func TestAskTooMuch(t *testing.T) {
+ test := allTests[0]
+ defer func() {
+ if recover() != nil {
+ t.Fatalf("Yikes, UnsafeFirst(%d, %s) panicked!", test.n, test.s)
+ }
+ }()
+ for _, test = range allTests {
+ switch res := UnsafeFirst(test.n, test.s); {
+ case len(test.out) > 0: // well, this should work
+ if res != test.out[0] {
+ t.Fatalf("Yikes, UnsafeFirst(%d, %s) = %q, want %q.",
+ test.n, test.s, res, test.out[0])
+ }
+ case len(res) != test.n:
+ t.Fatalf("Yikes, UnsafeFirst(%d, %s) = %q, but %q doesn't have %d characters.",
+ test.n, test.s, res, res, test.n)
+ default:
+ t.Fatalf("Yikes, UnsafeFirst(%d, %s) = %q, but %q isn't in %q",
+ test.n, test.s, res, res, test.s)
+ }
+ }
+}
diff --git a/go/series/first_test.go b/go/series/first_test.go
new file mode 100644
index 0000000..cbe524b
--- /dev/null
+++ b/go/series/first_test.go
@@ -0,0 +1,23 @@
+// +build first
+
+package slice
+
+import "testing"
+
+func TestFirst(t *testing.T) {
+ for _, test := range allTests {
+ switch res, ok := First(test.n, test.s); {
+ case !ok:
+ if len(test.out) > 0 {
+ t.Fatalf("First(%d, %s) returned !ok, want ok.",
+ test.n, test.s)
+ }
+ case len(test.out) == 0:
+ t.Fatalf("First(%d, %s) = %s, %t. Expected ok == false",
+ test.n, test.s, res, ok)
+ case res != test.out[0]:
+ t.Fatalf("First(%d, %s) = %s. Want %s.",
+ test.n, test.s, res, test.out[0])
+ }
+ }
+}
diff --git a/go/series/series.go b/go/series/series.go
new file mode 100644
index 0000000..55f7eb2
--- /dev/null
+++ b/go/series/series.go
@@ -0,0 +1,25 @@
+package slice
+
+// All returns a list of all substrings of s with length n.
+func All(n int, s string) []string {
+ var ret []string
+ for i, j := 0, n; j <= len(s); i, j = i+1, j+1 {
+ ret = append(ret, s[i:j])
+ }
+ return ret
+}
+
+// UnsafeFirst returns the first substring of s with length n.
+func UnsafeFirst(n int, s string) string {
+ if len(s) >= n {
+ return s[:n]
+ }
+ return ""
+}
+
+func First(n int, s string) (string, bool) {
+ if len(s) >= n {
+ return s[:n], true
+ }
+ return "", false
+}
diff --git a/go/series/series_test.go b/go/series/series_test.go
new file mode 100644
index 0000000..682d78f
--- /dev/null
+++ b/go/series/series_test.go
@@ -0,0 +1,94 @@
+// Define two functions: (Two? Yes, sometimes we ask more out of Go.)
+//
+// // All returns a list of all substrings of s with length n.
+// All(n int, s string) []string
+//
+// // UnsafeFirst returns the first substring of s with length n.
+// UnsafeFirst(n int, s string) string
+//
+// At this point you could consider this exercise complete and move on.
+// But wait, maybe you ask a reasonable question:
+// Why is the function called **Unsafe** First?
+// If you are interested, read on for a bonus exercise.
+//
+// Bonus exercise:
+//
+// Once you get `go test` passing, try `go test -tags asktoomuch`.
+// This uses a *build tag* to enable a test that wasn't enabled before.
+// You can read more about those at https://golang.org/pkg/go/build/#hdr-Build_Constraints
+//
+// You may notice that you can't make this asktoomuch test happy.
+// We need a way to signal that in some cases you can't take the first N characters of the string.
+// UnsafeFirst can't do that since it only returns a string.
+//
+// To fix that, let's add another return value to the function. Define
+//
+// First(int, string) (first string, ok bool)
+//
+// and test with `go test -tags first`.
+
+package slice
+
+import (
+ "reflect"
+ "testing"
+)
+
+var allTests = []struct {
+ n int
+ s string
+ out []string
+}{
+ {1, "01234",
+ []string{"0", "1", "2", "3", "4"}},
+ {1, "92834",
+ []string{"9", "2", "8", "3", "4"}},
+ {2, "01234",
+ []string{"01", "12", "23", "34"}},
+ {2, "98273463",
+ []string{"98", "82", "27", "73", "34", "46", "63"}},
+ {2, "37103",
+ []string{"37", "71", "10", "03"}},
+ {3, "01234",
+ []string{"012", "123", "234"}},
+ {3, "31001",
+ []string{"310", "100", "001"}},
+ {3, "982347",
+ []string{"982", "823", "234", "347"}},
+ {4, "01234",
+ []string{"0123", "1234"}},
+ {4, "91274",
+ []string{"9127", "1274"}},
+ {5, "01234",
+ []string{"01234"}},
+ {5, "81228",
+ []string{"81228"}},
+ {6, "01234", nil},
+ {len(cx) + 1, cx, nil},
+}
+
+var cx = "01032987583"
+
+func TestAll(t *testing.T) {
+ for _, test := range allTests {
+ switch res := All(test.n, test.s); {
+ case len(res) == 0 && len(test.out) == 0:
+ case reflect.DeepEqual(res, test.out):
+ default:
+ t.Fatalf("All(%d, %s) = %v, want %v.",
+ test.n, test.s, res, test.out)
+ }
+ }
+}
+
+func TestUnsafeFirst(t *testing.T) {
+ for _, test := range allTests {
+ if len(test.out) == 0 {
+ continue
+ }
+ if res := UnsafeFirst(test.n, test.s); res != test.out[0] {
+ t.Fatalf("UnsafeFirst(%d, %s) = %s, want %s.",
+ test.n, test.s, res, test.out[0])
+ }
+ }
+}