diff --git a/grains/.exercism/config.json b/grains/.exercism/config.json new file mode 100644 index 0000000..b81e706 --- /dev/null +++ b/grains/.exercism/config.json @@ -0,0 +1,40 @@ +{ + "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", + "authors": [ + "nathany" + ], + "contributors": [ + "alebaffa", + "bitfield", + "da-edra", + "dvrkps", + "ekingery", + "ferhatelmas", + "hilary", + "ilmanzo", + "johngb", + "kytrinyx", + "leenipper", + "petertseng", + "robphoenix", + "sebito91", + "strangeman", + "tleen" + ], + "files": { + "solution": [ + "grains.go" + ], + "test": [ + "grains_test.go" + ], + "example": [ + ".meta/example.go" + ], + "editor": [ + "cases_test.go" + ] + }, + "source": "JavaRanch Cattle Drive, exercise 6", + "source_url": "http://www.javaranch.com/grains.jsp" +} diff --git a/grains/.exercism/metadata.json b/grains/.exercism/metadata.json new file mode 100644 index 0000000..ee50fb9 --- /dev/null +++ b/grains/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"go","exercise":"grains","id":"f3ecefd420a344f3bb6ab0c9b6d176d6","url":"https://exercism.org/tracks/go/exercises/grains","handle":"koheiyamayama","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/grains/HELP.md b/grains/HELP.md new file mode 100644 index 0000000..ecd48e4 --- /dev/null +++ b/grains/HELP.md @@ -0,0 +1,40 @@ +# Help + +## Running the tests + +To run the tests run the command `go test` from within the exercise directory. + +If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` +flags: + + go test -v --bench . --benchmem + +Keep in mind that each reviewer will run benchmarks on a different machine, with +different specs, so the results from these benchmark tests may vary. + +## Submitting your solution + +You can submit your solution using the `exercism submit grains.go` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [Go track's documentation](https://exercism.org/docs/tracks/go) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [How to Write Go Code](https://golang.org/doc/code.html) +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Resources](http://golang.org/help) +- [StackOverflow](http://stackoverflow.com/questions/tagged/go) \ No newline at end of file diff --git a/grains/README.md b/grains/README.md new file mode 100644 index 0000000..bf22896 --- /dev/null +++ b/grains/README.md @@ -0,0 +1,62 @@ +# Grains + +Welcome to Grains on Exercism's Go Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +Calculate 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, with the number +of grains doubling on each successive square. + +There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on). + +Write code that shows: + +- how many grains were on a given square, and +- the total number of grains on the chessboard + +## 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? + +## Source + +### Created by + +- @nathany + +### Contributed to by + +- @alebaffa +- @bitfield +- @da-edra +- @dvrkps +- @ekingery +- @ferhatelmas +- @hilary +- @ilmanzo +- @johngb +- @kytrinyx +- @leenipper +- @petertseng +- @robphoenix +- @sebito91 +- @strangeman +- @tleen + +### Based on + +JavaRanch Cattle Drive, exercise 6 - http://www.javaranch.com/grains.jsp \ No newline at end of file diff --git a/grains/cases_test.go b/grains/cases_test.go new file mode 100644 index 0000000..4185710 --- /dev/null +++ b/grains/cases_test.go @@ -0,0 +1,64 @@ +package grains + +// Source: exercism/problem-specifications +// Commit: 2ec42ab Grains: Fixed canonical data to have standard error indicator (#1322) +// Problem Specifications Version: 1.2.0 + +// returns the number of grains on the square +var squareTests = []struct { + description string + input int + expectedVal uint64 + expectError bool +}{ + { + description: "1", + input: 1, + expectedVal: 1, + }, + { + description: "2", + input: 2, + expectedVal: 2, + }, + { + description: "3", + input: 3, + expectedVal: 4, + }, + { + description: "4", + input: 4, + expectedVal: 8, + }, + { + description: "16", + input: 16, + expectedVal: 32768, + }, + { + description: "32", + input: 32, + expectedVal: 2147483648, + }, + { + description: "64", + input: 64, + expectedVal: 9223372036854775808, + }, + { + description: "square 0 returns an error", + input: 0, + expectError: true, + }, + { + description: "negative square returns an error", + input: -1, + expectError: true, + }, + { + description: "square greater than 64 returns an error", + input: 65, + expectError: true, + }, +} diff --git a/grains/go.mod b/grains/go.mod new file mode 100644 index 0000000..5eed135 --- /dev/null +++ b/grains/go.mod @@ -0,0 +1,3 @@ +module grains + +go 1.16 diff --git a/grains/grains.go b/grains/grains.go new file mode 100644 index 0000000..513f7f2 --- /dev/null +++ b/grains/grains.go @@ -0,0 +1,27 @@ +package grains + +import ( + "errors" + "math" +) + +func Square(number int) (uint64, error) { + if number <= 0 || 64 < number { + return 0, errors.New("number must be greater than 0") + } + + return uint64(1 * math.Pow(float64(2), float64(number-1))), nil +} + +func Total() uint64 { + var sum uint64 = 0 + + for i := 0; i <= 64; i++ { + n, err := Square(i) + if err == nil { + sum += n + } + } + return sum + // return uint64(-1 * (1 - math.Pow(float64(2), float64(64)))) +} diff --git a/grains/grains_test.go b/grains/grains_test.go new file mode 100644 index 0000000..de031e1 --- /dev/null +++ b/grains/grains_test.go @@ -0,0 +1,57 @@ +package grains + +import ( + "testing" +) + +func TestSquare(t *testing.T) { + for _, test := range squareTests { + actualVal, actualErr := Square(test.input) + + // check actualVal only if no error expected + if !test.expectError && actualVal != test.expectedVal { + t.Fatalf("FAIL: %s\nSquare(%d) expected %d, Actual %d", test.description, test.input, test.expectedVal, actualVal) + } + + // if we expect an error and there isn't one + if test.expectError && actualErr == nil { + t.Fatalf("FAIL: %s\nSquare(%d) expected an error, but error is nil", test.description, test.input) + } + // if we don't expect an error and there is one + if !test.expectError && actualErr != nil { + var _ error = actualErr + t.Fatalf("FAIL: %s\nSquare(%d) expected no error, but error is: %s", test.description, test.input, actualErr) + } + t.Logf("PASS: %s", test.description) + } +} + +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) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + + for i := 0; i < b.N; i++ { + + for _, test := range squareTests { + Square(test.input) + } + + } +} + +func BenchmarkTotal(b *testing.B) { + if testing.Short() { + b.Skip("skipping benchmark in short mode.") + } + for i := 0; i < b.N; i++ { + Total() + } +}