summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-08-26 09:59:34 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-08-26 09:59:34 +0200
commita3817ba908b3705f96e572c48d5a9d96aae40118 (patch)
tree505b7eabcb376aac18837d197ca2f39722a0f1e3
parentcf38d5bfd8567e7b35a3e8e04998b87e38e7af94 (diff)
Solve grains
-rw-r--r--go/grains/README.md45
-rw-r--r--go/grains/grains.go19
-rw-r--r--go/grains/grains_test.go61
3 files changed, 125 insertions, 0 deletions
diff --git a/go/grains/README.md b/go/grains/README.md
new file mode 100644
index 0000000..3b9425a
--- /dev/null
+++ b/go/grains/README.md
@@ -0,0 +1,45 @@
+# Grains
+
+Write a program that calculates the number of grains of wheat on a chessboard given that the number on each square doubles.
+
+There once was a wise servant who saved the life of a prince. The king
+promised to pay whatever the servant could dream up. Knowing that the
+king loved chess, the servant told the king he would like to have grains
+of wheat. One grain on the first square of a chess board. Two grains on
+the next. Four on the third, and so on.
+
+There are 64 squares on a chessboard.
+
+Write a program that shows:
+- how many grains were on each square, and
+- the total number of grains
+
+
+## For bonus points
+
+Did you get the tests passing and the code clean? If you want to, these
+are some additional things you could try:
+
+- Optimize for speed.
+- Optimize for readability.
+
+Then please share your thoughts in a comment on the submission. Did this
+experiment make the code better? Worse? Did you learn anything from it?
+
+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
+
+JavaRanch Cattle Drive, exercise 6 [http://www.javaranch.com/grains.jsp](http://www.javaranch.com/grains.jsp)
+
+## 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/grains/grains.go b/go/grains/grains.go
new file mode 100644
index 0000000..22bbdda
--- /dev/null
+++ b/go/grains/grains.go
@@ -0,0 +1,19 @@
+package grains
+
+import "errors"
+
+func Square(n int) (uint64, error) {
+ if n < 1 || n > 64 {
+ return 0, errors.New("out of range")
+ }
+ return 1 << uint(n-1), nil
+}
+
+func Total() uint64 {
+ var n uint64
+ for i := 0; i < 64; i++ {
+ s, _ := Square(i + 1)
+ n += s
+ }
+ return n
+}
diff --git a/go/grains/grains_test.go b/go/grains/grains_test.go
new file mode 100644
index 0000000..e37cdab
--- /dev/null
+++ b/go/grains/grains_test.go
@@ -0,0 +1,61 @@
+package grains
+
+import (
+ "testing"
+)
+
+var squareTests = []struct {
+ input int
+ expectedVal uint64
+ expectError bool
+}{
+ {1, 1, false},
+ {2, 2, false},
+ {3, 4, false},
+ {4, 8, false},
+ {16, 32768, false},
+ {32, 2147483648, false},
+ {64, 9223372036854775808, false},
+ {65, 0, true},
+ {0, 0, true},
+ {-1, 0, true},
+}
+
+func TestSquare(t *testing.T) {
+ for _, test := range squareTests {
+ actualVal, actualErr := Square(test.input)
+ if actualVal != test.expectedVal {
+ t.Errorf("Square(%d) expected %d, Actual %d", test.input, test.expectedVal, actualVal)
+ }
+
+ // if we expect an error and there isn't one
+ if test.expectError && actualErr == nil {
+ t.Errorf("Square(%d) expected an error, but error is nil", test.input)
+ }
+ // if we don't expect an error and there is one
+ if !test.expectError && actualErr != nil {
+ t.Errorf("Square(%d) expected no error, but error is: %s", test.input, actualErr)
+ }
+ }
+}
+
+func TestTotal(t *testing.T) {
+ var expected uint64 = 18446744073709551615
+ if actual := Total(); actual != expected {
+ t.Errorf("Total() expected %d, Actual %d", expected, actual)
+ }
+}
+
+func BenchmarkSquare(b *testing.B) {
+ b.StopTimer()
+
+ for _, test := range squareTests {
+ b.StartTimer()
+
+ for i := 0; i < b.N; i++ {
+ Square(test.input)
+ }
+
+ b.StopTimer()
+ }
+}