diff options
author | Andinus <andinus@nand.sh> | 2021-08-11 15:26:15 +0530 |
---|---|---|
committer | Andinus <andinus@nand.sh> | 2021-08-11 15:26:15 +0530 |
commit | 321825828ac918bad28d0597a8616c6dc9802c3c (patch) | |
tree | 0b8e9cb1012197750eb58e972736319b2a6abac2 /go | |
parent | 2979ef790ac5b8f58495e0dd08cafd6a3a2e30a5 (diff) | |
download | exercism-321825828ac918bad28d0597a8616c6dc9802c3c.tar.gz |
Add solved exercises
Diffstat (limited to 'go')
34 files changed, 998 insertions, 0 deletions
diff --git a/go/hamming/README.md b/go/hamming/README.md new file mode 100644 index 0000000..49e180d --- /dev/null +++ b/go/hamming/README.md @@ -0,0 +1,59 @@ +# Hamming + +Calculate the Hamming Distance between two DNA strands. + +Your body is made up of cells that contain DNA. Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime! + +When cells divide, their DNA replicates too. Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. If we compare two strands of DNA and count the differences between them we can see how many mistakes occurred. This is known as the "Hamming Distance". + +We read DNA using the letters C,A,G and T. Two strands might look like this: + + GAGCCTACTAACGGGAT + CATCGTAATGACGGCCT + ^ ^ ^ ^ ^ ^^ + +They have 7 differences, and therefore the Hamming Distance is 7. + +The Hamming Distance is useful for lots of things in science, not just biology, so it's a nice phrase to be familiar with :) + +# Implementation notes + +The Hamming distance is only defined for sequences of equal length, so +an attempt to calculate it between sequences of different lengths should +not work. The general handling of this situation (e.g., raising an +exception vs returning a special value) may differ between languages. + +You may be wondering about the `cases_test.go` file. We explain it in the +[leap exercise][leap-exercise-readme]. + +[leap-exercise-readme]: https://github.com/exercism/go/blob/master/exercises/leap/README.md + + +## Coding the solution + +Look for a stub file having the name hamming.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +The Calculating Point Mutations problem at Rosalind [http://rosalind.info/problems/hamm/](http://rosalind.info/problems/hamm/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/hamming/cases_test.go b/go/hamming/cases_test.go new file mode 100644 index 0000000..84e867c --- /dev/null +++ b/go/hamming/cases_test.go @@ -0,0 +1,67 @@ +package hamming + +// Source: exercism/problem-specifications +// Commit: 4119671 Hamming: Add a tests to avoid wrong recursion solution (#1450) +// Problem Specifications Version: 2.3.0 + +var testCases = []struct { + s1 string + s2 string + want int + expectError bool +}{ + { // empty strands + "", + "", + 0, + false, + }, + { // single letter identical strands + "A", + "A", + 0, + false, + }, + { // single letter different strands + "G", + "T", + 1, + false, + }, + { // long identical strands + "GGACTGAAATCTG", + "GGACTGAAATCTG", + 0, + false, + }, + { // long different strands + "GGACGGATTCTG", + "AGGACGGATTCT", + 9, + false, + }, + { // disallow first strand longer + "AATG", + "AAA", + 0, + true, + }, + { // disallow second strand longer + "ATA", + "AGTG", + 0, + true, + }, + { // disallow left empty strand + "", + "G", + 0, + true, + }, + { // disallow right empty strand + "G", + "", + 0, + true, + }, +} diff --git a/go/hamming/go.mod b/go/hamming/go.mod new file mode 100644 index 0000000..f37db60 --- /dev/null +++ b/go/hamming/go.mod @@ -0,0 +1,3 @@ +module hamming + +go 1.13 diff --git a/go/hamming/hamming.go b/go/hamming/hamming.go new file mode 100644 index 0000000..a019855 --- /dev/null +++ b/go/hamming/hamming.go @@ -0,0 +1,18 @@ +// hamming implements Distance. +package hamming + +import "errors" + +// Distance returns the distance between 2 equal DNA strands. +func Distance(strand1, strand2 string) (int, error) { + var dist int + if len(strand1) != len(strand2) { + return dist, errors.New("length not equal") + } + for idx := 0; idx < len(strand1); idx++ { + if strand1[idx] != strand2[idx] { + dist++ + } + } + return dist, nil +} diff --git a/go/hamming/hamming_test.go b/go/hamming/hamming_test.go new file mode 100644 index 0000000..82e8a8e --- /dev/null +++ b/go/hamming/hamming_test.go @@ -0,0 +1,40 @@ +package hamming + +import "testing" + +func TestHamming(t *testing.T) { + for _, tc := range testCases { + got, err := Distance(tc.s1, tc.s2) + if tc.expectError { + // check if err is of error type + var _ error = err + + // we expect error + if err == nil { + t.Fatalf("Distance(%q, %q); expected error, got nil.", + tc.s1, tc.s2) + } + } else { + // we do not expect error + if err != nil { + t.Fatalf("Distance(%q, %q) returned unexpected error: %v", + tc.s1, tc.s2, err) + } + if got != tc.want { + t.Fatalf("Distance(%q, %q) = %d, want %d.", + tc.s1, tc.s2, got, tc.want) + } + + } + } +} + +func BenchmarkHamming(b *testing.B) { + // bench combined time to run through all test cases + for i := 0; i < b.N; i++ { + for _, tc := range testCases { + // ignoring errors and results because we're just timing function execution + _, _ = Distance(tc.s1, tc.s2) + } + } +} diff --git a/go/hello-world/README.md b/go/hello-world/README.md new file mode 100644 index 0000000..13dd5c8 --- /dev/null +++ b/go/hello-world/README.md @@ -0,0 +1,44 @@ +# Hello World + +The classical introductory exercise. Just say "Hello, World!". + +["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is +the traditional first program for beginning programming in a new language +or environment. + +The objectives are simple: + +- Write a function that returns the string "Hello, World!". +- Run the test suite and make sure that it succeeds. +- Submit your solution and check it at the website. + +If everything goes well, you will be ready to fetch your first real exercise. + +## Coding the solution + +Look for a stub file having the name hello_world.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/hello-world/go.mod b/go/hello-world/go.mod new file mode 100644 index 0000000..5bfa5f6 --- /dev/null +++ b/go/hello-world/go.mod @@ -0,0 +1,3 @@ +module greeting + +go 1.13 diff --git a/go/hello-world/hello_world.go b/go/hello-world/hello_world.go new file mode 100644 index 0000000..781e41f --- /dev/null +++ b/go/hello-world/hello_world.go @@ -0,0 +1,7 @@ +// Implements HelloWorld. +package greeting + +// HelloWorld returns "Hello, World!". +func HelloWorld() string { + return "Hello, World!" +} diff --git a/go/hello-world/hello_world_test.go b/go/hello-world/hello_world_test.go new file mode 100644 index 0000000..bf6cb90 --- /dev/null +++ b/go/hello-world/hello_world_test.go @@ -0,0 +1,37 @@ +package greeting + +import "testing" + +// Define a function named HelloWorld that takes no arguments, +// and returns a string. +// In other words, define a function with the following signature: +// HelloWorld() string + +func TestHelloWorld(t *testing.T) { + expected := "Hello, World!" + if observed := HelloWorld(); observed != expected { + t.Fatalf("HelloWorld() = %v, want %v", observed, expected) + } +} + +// BenchmarkHelloWorld() is a benchmarking function. These functions follow the +// form `func BenchmarkXxx(*testing.B)` and can be used to test the performance +// of your implementation. They may not be present in every exercise, but when +// they are you can run them by including the `-bench` flag with the `go test` +// command, like so: `go test -v --bench . --benchmem` +// +// You will see output similar to the following: +// +// BenchmarkHelloWorld 2000000000 0.46 ns/op +// +// This means that the loop ran 2000000000 times at a speed of 0.46 ns per loop. +// +// While benchmarking can be useful to compare different iterations of the same +// exercise, keep in mind that others will run the same benchmarks on different +// machines, with different specs, so the results from these benchmark tests may +// vary. +func BenchmarkHelloWorld(b *testing.B) { + for i := 0; i < b.N; i++ { + HelloWorld() + } +} diff --git a/go/leap/README.md b/go/leap/README.md new file mode 100644 index 0000000..84ba774 --- /dev/null +++ b/go/leap/README.md @@ -0,0 +1,69 @@ +# Leap + +Given a year, report if it is a leap year. + +The tricky thing here is that a leap year in the Gregorian calendar occurs: + +```text +on every year that is evenly divisible by 4 + except every year that is evenly divisible by 100 + unless the year is also evenly divisible by 400 +``` + +For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap +year, but 2000 is. + +## Notes + +Though our exercise adopts some very simple rules, there is more to +learn! + +For a delightful, four minute explanation of the whole leap year +phenomenon, go watch [this youtube video][video]. + +[video]: http://www.youtube.com/watch?v=xX96xng7sAE + +You will see a `cases_test.go` file in this exercise. This holds the test +cases used in the `leap_test.go`. You can mostly ignore this file. + +However, if you are interested... we sometimes generate the test data from a +[cross language repository][problem-specifications-leap]. In that repo +exercises may have a [.json file][problem-specifications-leap-json] that +contains common test data. Some of our local exercises have an +[intermediary program][local-leap-gen] that takes the problem specification +JSON and turns in into Go structs that are fed into the `<exercise>_test.go` +file. The Go specific transformation of that data lives in the `cases_test.go` file. + +[problem-specifications-leap]: https://github.com/exercism/problem-specifications/tree/master/exercises/leap +[problem-specifications-leap-json]: https://github.com/exercism/problem-specifications/blob/master/exercises/leap/canonical-data.json +[local-leap-gen]: https://github.com/exercism/go/blob/master/exercises/leap/.meta/gen.go + + +## Coding the solution + +Look for a stub file having the name leap.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +JavaRanch Cattle Drive, exercise 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.jsp) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/leap/cases_test.go b/go/leap/cases_test.go new file mode 100644 index 0000000..f9e8c04 --- /dev/null +++ b/go/leap/cases_test.go @@ -0,0 +1,18 @@ +package leap + +// Source: exercism/problem-specifications +// Commit: 18875ec Leap: Improve the specification so that code generation is more readable - … (#1468) +// Problem Specifications Version: 1.5.1 + +var testCases = []struct { + year int + expected bool + description string +}{ + {2015, false, "year not divisible by 4 in common year"}, + {1970, false, "year divisible by 2, not divisible by 4 in common year"}, + {1996, true, "year divisible by 4, not divisible by 100 in leap year"}, + {2100, false, "year divisible by 100, not divisible by 400 in common year"}, + {2000, true, "year divisible by 400 in leap year"}, + {1800, false, "year divisible by 200, not divisible by 400 in common year"}, +} diff --git a/go/leap/go.mod b/go/leap/go.mod new file mode 100644 index 0000000..bdbf06a --- /dev/null +++ b/go/leap/go.mod @@ -0,0 +1,3 @@ +module leap + +go 1.13 diff --git a/go/leap/leap.go b/go/leap/leap.go new file mode 100644 index 0000000..e56ff65 --- /dev/null +++ b/go/leap/leap.go @@ -0,0 +1,7 @@ +// leap implements IsLeapYear. +package leap + +// IsLeapYear returns if the year passed is a leap year. +func IsLeapYear(year int) bool { + return year%4 == 0 && (year%100 != 0 || year%400 == 0) +} diff --git a/go/leap/leap_test.go b/go/leap/leap_test.go new file mode 100644 index 0000000..eabd1f2 --- /dev/null +++ b/go/leap/leap_test.go @@ -0,0 +1,22 @@ +package leap + +import "testing" + +func TestLeapYears(t *testing.T) { + for _, test := range testCases { + observed := IsLeapYear(test.year) + if observed != test.expected { + t.Fatalf("IsLeapYear(%d) = %t, want %t (%s)", + test.year, observed, test.expected, test.description) + } + } +} + +// Benchmark 400 year interval to get fair weighting of different years. +func Benchmark400(b *testing.B) { + for i := 0; i < b.N; i++ { + for y := 1600; y < 2000; y++ { + IsLeapYear(y) + } + } +} diff --git a/go/nucleotide-count/README.md b/go/nucleotide-count/README.md new file mode 100644 index 0000000..be96783 --- /dev/null +++ b/go/nucleotide-count/README.md @@ -0,0 +1,64 @@ +# Nucleotide Count + +Given a single stranded DNA string, compute how many times each nucleotide occurs in the string. + +The genetic language of every living thing on the planet is DNA. +DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides. +4 types exist in DNA and these differ only slightly and can be represented as the following symbols: 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' thymine. + +Here is an analogy: +- twigs are to birds nests as +- nucleotides are to DNA as +- legos are to lego houses as +- words are to sentences as... + +## Implementation + +You should define a custom type 'DNA' with a function 'Counts' that outputs two values: + +- a frequency count for the given DNA strand +- an error (if there are invalid nucleotides) + +Which is a good type for a DNA strand ? + +Which is the best Go types to represent the output values ? + +Take a look at the test cases to get a hint about what could be the possible inputs. + + +## note about the tests +You may be wondering about the `cases_test.go` file. We explain it in the +[leap exercise][leap-exercise-readme]. + +[leap-exercise-readme]: https://github.com/exercism/go/blob/master/exercises/leap/README.md + + + +## Coding the solution + +Look for a stub file having the name nucleotide_count.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +The Calculating DNA Nucleotides_problem at Rosalind [http://rosalind.info/problems/dna/](http://rosalind.info/problems/dna/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/nucleotide-count/cases_test.go b/go/nucleotide-count/cases_test.go new file mode 100644 index 0000000..98d5cac --- /dev/null +++ b/go/nucleotide-count/cases_test.go @@ -0,0 +1,39 @@ +package dna + +// Source: exercism/problem-specifications +// Commit: 879a096 nucleotide-count: Apply new "input" policy +// Problem Specifications Version: 1.3.0 + +// count all nucleotides in a strand +var testCases = []struct { + description string + strand string + expected Histogram + errorExpected bool +}{ + { + description: "empty strand", + strand: "", + expected: Histogram{'A': 0, 'C': 0, 'G': 0, 'T': 0}, + }, + { + description: "can count one nucleotide in single-character input", + strand: "G", + expected: Histogram{'A': 0, 'C': 0, 'G': 1, 'T': 0}, + }, + { + description: "strand with repeated nucleotide", + strand: "GGGGGGG", + expected: Histogram{'A': 0, 'C': 0, 'G': 7, 'T': 0}, + }, + { + description: "strand with multiple nucleotides", + strand: "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC", + expected: Histogram{'A': 20, 'C': 12, 'G': 17, 'T': 21}, + }, + { + description: "strand with invalid nucleotides", + strand: "AGXXACT", + errorExpected: true, + }, +} diff --git a/go/nucleotide-count/go.mod b/go/nucleotide-count/go.mod new file mode 100644 index 0000000..ee07bad --- /dev/null +++ b/go/nucleotide-count/go.mod @@ -0,0 +1,3 @@ +module dna + +go 1.13 diff --git a/go/nucleotide-count/nucleotide_count.go b/go/nucleotide-count/nucleotide_count.go new file mode 100644 index 0000000..1fb532c --- /dev/null +++ b/go/nucleotide-count/nucleotide_count.go @@ -0,0 +1,19 @@ +package dna + +// Histogram is a mapping from nucleotide to its count in given DNA. +// Choose a suitable data type. +type Histogram + +// DNA is a list of nucleotides. Choose a suitable data type. +type DNA + +// Counts generates a histogram of valid nucleotides in the given DNA. +// Returns an error if d contains an invalid nucleotide. +/// +// Counts is a method on the DNA type. A method is a function with a special receiver argument. +// The receiver appears in its own argument list between the func keyword and the method name. +// Here, the Counts method has a receiver of type DNA named d. +func (d DNA) Counts() (Histogram, error) { + var h Histogram + return h, nil +} diff --git a/go/nucleotide-count/nucleotide_count_test.go b/go/nucleotide-count/nucleotide_count_test.go new file mode 100644 index 0000000..247f8db --- /dev/null +++ b/go/nucleotide-count/nucleotide_count_test.go @@ -0,0 +1,27 @@ +package dna + +import ( + "reflect" + "testing" +) + +func TestCounts(t *testing.T) { + for _, tc := range testCases { + dna := DNA(tc.strand) + s, err := dna.Counts() + switch { + case tc.errorExpected: + if err == nil { + t.Fatalf("FAIL: %s\nCounts(%q)\nExpected error\nActual: %#v", + tc.description, tc.strand, s) + } + case err != nil: + t.Fatalf("FAIL: %s\nCounts(%q)\nExpected: %#v\nGot error: %q", + tc.description, tc.strand, tc.expected, err) + case !reflect.DeepEqual(s, tc.expected): + t.Fatalf("FAIL: %s\nCounts(%q)\nExpected: %#v\nActual: %#v", + tc.description, tc.strand, tc.expected, s) + } + t.Logf("PASS: %s", tc.description) + } +} diff --git a/go/raindrops/README.md b/go/raindrops/README.md new file mode 100644 index 0000000..71db66d --- /dev/null +++ b/go/raindrops/README.md @@ -0,0 +1,56 @@ +# Raindrops + +Your task is to convert a number into a string that contains raindrop sounds corresponding to certain potential factors. A factor is a number that evenly divides into another number, leaving no remainder. The simplest way to test if a one number is a factor of another is to use the [modulo operation](https://en.wikipedia.org/wiki/Modulo_operation). + +The rules of `raindrops` are that if a given number: + +- has 3 as a factor, add 'Pling' to the result. +- has 5 as a factor, add 'Plang' to the result. +- has 7 as a factor, add 'Plong' to the result. +- _does not_ have any of 3, 5, or 7 as a factor, the result should be the digits of the number. + +## Examples + +- 28 has 7 as a factor, but not 3 or 5, so the result would be "Plong". +- 30 has both 3 and 5 as factors, but not 7, so the result would be "PlingPlang". +- 34 is not factored by 3, 5, or 7, so the result would be "34". + +## Simple Stub + +The raindrops.go "stub file" contains only one line with the correct +package name and nothing more. This will be the usual pattern for future +exercises. You will need to figure out the function signature(s). + +One way to figure out the function signature(s) is to look +at the corresponding \*\_test.go file. It will show the package level +functions(s) that the test will use to verify the solution. + + +## Coding the solution + +Look for a stub file having the name raindrops.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +A variation on FizzBuzz, a famous technical interview question that is intended to weed out potential candidates. That question is itself derived from Fizz Buzz, a popular children's game for teaching division. [https://en.wikipedia.org/wiki/Fizz_buzz](https://en.wikipedia.org/wiki/Fizz_buzz) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/raindrops/cases_test.go b/go/raindrops/cases_test.go new file mode 100644 index 0000000..ea6becd --- /dev/null +++ b/go/raindrops/cases_test.go @@ -0,0 +1,29 @@ +package raindrops + +// Source: exercism/problem-specifications +// Commit: 99de15d raindrops: apply "input" policy +// Problem Specifications Version: 1.1.0 + +var tests = []struct { + input int + expected string +}{ + {1, "1"}, + {3, "Pling"}, + {5, "Plang"}, + {7, "Plong"}, + {6, "Pling"}, + {8, "8"}, + {9, "Pling"}, + {10, "Plang"}, + {14, "Plong"}, + {15, "PlingPlang"}, + {21, "PlingPlong"}, + {25, "Plang"}, + {27, "Pling"}, + {35, "PlangPlong"}, + {49, "Plong"}, + {52, "52"}, + {105, "PlingPlangPlong"}, + {3125, "Plang"}, +} diff --git a/go/raindrops/go.mod b/go/raindrops/go.mod new file mode 100644 index 0000000..9454edc --- /dev/null +++ b/go/raindrops/go.mod @@ -0,0 +1,3 @@ +module raindrops + +go 1.13 diff --git a/go/raindrops/raindrops.go b/go/raindrops/raindrops.go new file mode 100644 index 0000000..1ddc5a7 --- /dev/null +++ b/go/raindrops/raindrops.go @@ -0,0 +1,39 @@ +// Package raindrops implements Convert. +package raindrops + +import "strconv" + +type raindrop struct { + div int + res string +} + +// Convert returns a string given an integer. +// +// - adds "Pling" to the result if the number is divisible by 3. +// +// - adds "Plang" to the result if the number is divisible by 5. +// +// - adds "Plong" to the result if the number is divisible by 7. +// +// - if it's not divisible by 3, 5 or 7 then the digits of given +// integer is returned. +func Convert(num int) string { + var res string + var drops = [3]raindrop{ + {3, "Pling"}, + {5, "Plang"}, + {7, "Plong"}, + } + + for _, drop := range drops { + if num%drop.div == 0 { + res += drop.res + } + } + if len(res) == 0 { + res = strconv.Itoa(num) + } + + return res +} diff --git a/go/raindrops/raindrops_test.go b/go/raindrops/raindrops_test.go new file mode 100644 index 0000000..14f0983 --- /dev/null +++ b/go/raindrops/raindrops_test.go @@ -0,0 +1,20 @@ +package raindrops + +import "testing" + +func TestConvert(t *testing.T) { + for _, test := range tests { + if actual := Convert(test.input); actual != test.expected { + t.Errorf("Convert(%d) = %q, expected %q.", + test.input, actual, test.expected) + } + } +} + +func BenchmarkConvert(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, test := range tests { + Convert(test.input) + } + } +} diff --git a/go/space-age/README.md b/go/space-age/README.md new file mode 100644 index 0000000..0ebf7a5 --- /dev/null +++ b/go/space-age/README.md @@ -0,0 +1,64 @@ +# Space Age + +Given an age in seconds, calculate how old someone would be on: + + - Mercury: orbital period 0.2408467 Earth years + - Venus: orbital period 0.61519726 Earth years + - Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds + - Mars: orbital period 1.8808158 Earth years + - Jupiter: orbital period 11.862615 Earth years + - Saturn: orbital period 29.447498 Earth years + - Uranus: orbital period 84.016846 Earth years + - Neptune: orbital period 164.79132 Earth years + +So if you were told someone were 1,000,000,000 seconds old, you should +be able to say that they're 31.69 Earth-years old. + +If you're wondering why Pluto didn't make the cut, go watch [this +youtube video](http://www.youtube.com/watch?v=Z_2gbGXzFbs). + +## Simple Stub + +The space_age.go "stub file" contains only one line with the correct +package name and nothing more. This will be the usual pattern for future +exercises. You will need to figure out the function signature(s). + +One way to figure out the function signature(s) is to look +at the corresponding \*\_test.go file. It will show the package level +functions(s) that the test will use to verify the solution. + +## Planet Type + +The test cases make use of a custom `Planet` type that is sent to your function. +You will need to implement this custom type yourself. +Implementing this new custom type as a string should suffice. + + +## Coding the solution + +Look for a stub file having the name space_age.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=01](http://pine.fm/LearnToProgram/?Chapter=01) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/space-age/cases_test.go b/go/space-age/cases_test.go new file mode 100644 index 0000000..5280b07 --- /dev/null +++ b/go/space-age/cases_test.go @@ -0,0 +1,61 @@ +package space + +// Source: exercism/problem-specifications +// Commit: 28b3dac0 space-age: restrict seconds to fit within 32-bit int range +// Problem Specifications Version: 1.2.0 + +var testCases = []struct { + description string + planet Planet + seconds float64 + expected float64 +}{ + { + description: "age on Earth", + planet: "Earth", + seconds: 1000000000, + expected: 31.69, + }, + { + description: "age on Mercury", + planet: "Mercury", + seconds: 2134835688, + expected: 280.88, + }, + { + description: "age on Venus", + planet: "Venus", + seconds: 189839836, + expected: 9.78, + }, + { + description: "age on Mars", + planet: "Mars", + seconds: 2129871239, + expected: 35.88, + }, + { + description: "age on Jupiter", + planet: "Jupiter", + seconds: 901876382, + expected: 2.41, + }, + { + description: "age on Saturn", + planet: "Saturn", + seconds: 2000000000, + expected: 2.15, + }, + { + description: "age on Uranus", + planet: "Uranus", + seconds: 1210123456, + expected: 0.46, + }, + { + description: "age on Neptune", + planet: "Neptune", + seconds: 1821023456, + expected: 0.35, + }, +} diff --git a/go/space-age/go.mod b/go/space-age/go.mod new file mode 100644 index 0000000..1847ac2 --- /dev/null +++ b/go/space-age/go.mod @@ -0,0 +1,3 @@ +module space + +go 1.13 diff --git a/go/space-age/space_age.go b/go/space-age/space_age.go new file mode 100644 index 0000000..249ff90 --- /dev/null +++ b/go/space-age/space_age.go @@ -0,0 +1,27 @@ +package space + +type Planet string + +func Age(seconds float64, planet Planet) float64 { + const earthSeconds float64 = 31557600 + + switch planet { + case "Mercury": + return seconds / (0.2408467 * earthSeconds) + case "Venus": + return seconds / (0.61519726 * earthSeconds) + case "Earth": + return seconds / (1.0 * earthSeconds) + case "Mars": + return seconds / (1.8808158 * earthSeconds) + case "Jupiter": + return seconds / (11.862615 * earthSeconds) + case "Saturn": + return seconds / (29.447498 * earthSeconds) + case "Uranus": + return seconds / (84.016846 * earthSeconds) + case "Neptune": + return seconds / (164.79132 * earthSeconds) + } + return -1 +} diff --git a/go/space-age/space_age_test.go b/go/space-age/space_age_test.go new file mode 100644 index 0000000..71f7359 --- /dev/null +++ b/go/space-age/space_age_test.go @@ -0,0 +1,25 @@ +package space + +import ( + "math" + "testing" +) + +func TestAge(t *testing.T) { + const precision = 0.01 + for _, tc := range testCases { + actual := Age(tc.seconds, tc.planet) + if math.IsNaN(actual) || math.Abs(actual-tc.expected) > precision { + t.Fatalf("FAIL: %s\nExpected: %#v\nActual: %#v", tc.description, tc.expected, actual) + } + t.Logf("PASS: %s", tc.description) + } +} + +func BenchmarkAge(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, tc := range testCases { + Age(tc.seconds, tc.planet) + } + } +} diff --git a/go/two-fer/README.md b/go/two-fer/README.md new file mode 100644 index 0000000..4fd3018 --- /dev/null +++ b/go/two-fer/README.md @@ -0,0 +1,55 @@ +# Two Fer + +`Two-fer` or `2-fer` is short for two for one. One for you and one for me. + +Given a name, return a string with the message: + +```text +One for X, one for me. +``` + +Where X is the given name. + +However, if the name is missing, return the string: + +```text +One for you, one for me. +``` + +Here are some examples: + +|Name |String to return +|:-------|:------------------ +|Alice |One for Alice, one for me. +|Bob |One for Bob, one for me. +| |One for you, one for me. +|Zaphod |One for Zaphod, one for me. + +## Coding the solution + +Look for a stub file having the name two_fer.go +and place your solution code in that file. + +## 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. + +## Further information + +For more detailed information about the Go track, including how to get help if +you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/resources). + +## Source + +[https://github.com/exercism/problem-specifications/issues/757](https://github.com/exercism/problem-specifications/issues/757) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/go/two-fer/example_two_fer_test.go b/go/two-fer/example_two_fer_test.go new file mode 100644 index 0000000..fe0f023 --- /dev/null +++ b/go/two-fer/example_two_fer_test.go @@ -0,0 +1,20 @@ +package twofer + +import "fmt" + +// ExampleShareWith() is an Example function. Examples are testable snippets of +// Go code that are used for documenting and verifying the package API. +// They may be present in some exercises to demonstrate the expected use of the +// exercise API and can be run as part of a package's test suite. +// +// When an Example test is run the data that is written to standard output is +// compared to the data that comes after the "Output: " comment. +// +// Below the result of ShareWith() is passed to standard output +// using fmt.Println, and this is compared against the expected output. +// If they are equal, the test passes. +func ExampleShareWith() { + h := ShareWith("") + fmt.Println(h) + // Output: One for you, one for me. +} diff --git a/go/two-fer/go.mod b/go/two-fer/go.mod new file mode 100644 index 0000000..3eebc29 --- /dev/null +++ b/go/two-fer/go.mod @@ -0,0 +1,3 @@ +module twofer + +go 1.13 diff --git a/go/two-fer/two_fer.go b/go/two-fer/two_fer.go new file mode 100644 index 0000000..3497a4c --- /dev/null +++ b/go/two-fer/two_fer.go @@ -0,0 +1,13 @@ +// twofer implements ShareWith. +package twofer + +import "fmt" + +// ShareWith returns "One for `name', one for me.". Default name is +// "you". +func ShareWith(name string) string { + if len(name) == 0 { + name = "you" + } + return fmt.Sprintf("One for %s, one for me.", name) +} diff --git a/go/two-fer/two_fer_test.go b/go/two-fer/two_fer_test.go new file mode 100644 index 0000000..f4ce158 --- /dev/null +++ b/go/two-fer/two_fer_test.go @@ -0,0 +1,31 @@ +package twofer + +import "testing" + +// Define a function ShareWith(string) string. + +var tests = []struct { + name, expected string +}{ + {"", "One for you, one for me."}, + {"Alice", "One for Alice, one for me."}, + {"Bob", "One for Bob, one for me."}, +} + +func TestShareWith(t *testing.T) { + for _, test := range tests { + if observed := ShareWith(test.name); observed != test.expected { + t.Fatalf("ShareWith(%s) = \"%v\", want \"%v\"", test.name, observed, test.expected) + } + } +} + +func BenchmarkShareWith(b *testing.B) { + for i := 0; i < b.N; i++ { + + for _, test := range tests { + ShareWith(test.name) + } + + } +} |