summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-08-25 03:13:39 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-08-25 03:13:39 +0200
commit509c5063d66e8bbef4ec1def1c99c318be51aceb (patch)
treeafc811c4781a4e317043e2a0237499defc168044
Initial import
-rw-r--r--go/bob/README.md48
-rw-r--r--go/bob/bob.go32
-rw-r--r--go/bob/bob_test.go30
-rw-r--r--go/bob/cases_test.go141
-rw-r--r--go/clock/README.md27
-rw-r--r--go/clock/cases_test.go152
-rw-r--r--go/clock/clock.go29
-rw-r--r--go/clock/clock_test.go83
-rw-r--r--go/gigasecond/README.md23
-rw-r--r--go/gigasecond/cases_test.go31
-rw-r--r--go/gigasecond/gigasecond.go9
-rw-r--r--go/gigasecond/gigasecond_test.go63
-rw-r--r--go/hamming/README.md54
-rw-r--r--go/hamming/cases_test.go81
-rw-r--r--go/hamming/hamming.go18
-rw-r--r--go/hamming/hamming_test.go36
-rw-r--r--go/hello-world/README.md58
-rw-r--r--go/hello-world/hello_test.go29
-rw-r--r--go/hello-world/hello_world.go11
-rw-r--r--go/leap/README.md45
-rw-r--r--go/leap/cases_test.go17
-rw-r--r--go/leap/leap.go8
-rw-r--r--go/leap/leap_test.go32
-rw-r--r--go/raindrops/README.md37
-rw-r--r--go/raindrops/cases_test.go25
-rw-r--r--go/raindrops/raindrops.go21
-rw-r--r--go/raindrops/raindrops_test.go25
-rw-r--r--go/triangle/.triangle.go.swpbin0 -> 12288 bytes
-rw-r--r--go/triangle/README.md29
-rw-r--r--go/triangle/triangle.go17
-rw-r--r--go/triangle/triangle_test.go99
31 files changed, 1310 insertions, 0 deletions
diff --git a/go/bob/README.md b/go/bob/README.md
new file mode 100644
index 0000000..1ed49ff
--- /dev/null
+++ b/go/bob/README.md
@@ -0,0 +1,48 @@
+# Bob
+
+Bob is a lackadaisical teenager. In conversation, his responses are very limited.
+
+Bob answers 'Sure.' if you ask him a question.
+
+He answers 'Whoa, chill out!' if you yell at him.
+
+He says 'Fine. Be that way!' if you address him without actually saying
+anything.
+
+He answers 'Whatever.' to anything else.
+
+## Instructions
+
+Run the test file, and fix each of the errors in turn. When you get the
+first test to pass, go to the first pending or skipped test, and make
+that pass as well. When all of the tests are passing, feel free to
+submit.
+
+Remember that passing code is just the first step. The goal is to work
+towards a solution that is as readable and expressive as you can make
+it.
+
+Please make your solution as general as possible. Good code doesn't just
+pass the test suite, it works with any input that fits the
+specification.
+
+Have fun!
+
+
+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
+
+Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=06](http://pine.fm/LearnToProgram/?Chapter=06)
+
+## 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/bob/bob.go b/go/bob/bob.go
new file mode 100644
index 0000000..129c0aa
--- /dev/null
+++ b/go/bob/bob.go
@@ -0,0 +1,32 @@
+package bob
+
+import (
+ "strings"
+ "unicode"
+)
+
+const testVersion = 2
+
+func Hey(s string) string {
+ s = strings.TrimSpace(s)
+ var hasUpper bool
+ var hasLower bool
+ for _, r := range s {
+ switch {
+ case unicode.IsUpper(r):
+ hasUpper = true
+ case unicode.IsLower(r):
+ hasLower = true
+ }
+ }
+ switch {
+ case hasUpper && !hasLower:
+ return "Whoa, chill out!"
+ case strings.HasSuffix(s, "?"):
+ return "Sure."
+ case len(s) == 0:
+ return "Fine. Be that way!"
+ default:
+ return "Whatever."
+ }
+}
diff --git a/go/bob/bob_test.go b/go/bob/bob_test.go
new file mode 100644
index 0000000..e53226d
--- /dev/null
+++ b/go/bob/bob_test.go
@@ -0,0 +1,30 @@
+package bob
+
+import "testing"
+
+const targetTestVersion = 2
+
+func TestHeyBob(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
+ }
+ for _, tt := range testCases {
+ actual := Hey(tt.input)
+ if actual != tt.expected {
+ msg := `
+ ALICE (%s): %q
+ BOB: %s
+
+ Expected Bob to respond: %s`
+ t.Fatalf(msg, tt.description, tt.input, actual, tt.expected)
+ }
+ }
+}
+
+func BenchmarkBob(b *testing.B) {
+ for _, tt := range testCases {
+ for i := 0; i < b.N; i++ {
+ Hey(tt.input)
+ }
+ }
+}
diff --git a/go/bob/cases_test.go b/go/bob/cases_test.go
new file mode 100644
index 0000000..825d11d
--- /dev/null
+++ b/go/bob/cases_test.go
@@ -0,0 +1,141 @@
+package bob
+
+// Source: exercism/x-common
+// Commit: 945d08e Merge pull request #50 from soniakeys/master
+
+var testCases = []struct {
+ description string
+ input string
+ expected string
+}{
+ {
+ "stating something",
+ "Tom-ay-to, tom-aaaah-to.",
+ "Whatever.",
+ },
+ {
+ "shouting",
+ "WATCH OUT!",
+ "Whoa, chill out!",
+ },
+ {
+ "shouting gibberish",
+ "FCECDFCAAB",
+ "Whoa, chill out!",
+ },
+ {
+ "asking a question",
+ "Does this cryogenic chamber make me look fat?",
+ "Sure.",
+ },
+ {
+ "asking a numeric question",
+ "You are, what, like 15?",
+ "Sure.",
+ },
+ {
+ "asking gibberish",
+ "fffbbcbeab?",
+ "Sure.",
+ },
+ {
+ "talking forcefully",
+ "Let's go make out behind the gym!",
+ "Whatever.",
+ },
+ {
+ "using acronyms in regular speech",
+ "It's OK if you don't want to go to the DMV.",
+ "Whatever.",
+ },
+ {
+ "forceful question",
+ "WHAT THE HELL WERE YOU THINKING?",
+ "Whoa, chill out!",
+ },
+ {
+ "shouting numbers",
+ "1, 2, 3 GO!",
+ "Whoa, chill out!",
+ },
+ {
+ "only numbers",
+ "1, 2, 3",
+ "Whatever.",
+ },
+ {
+ "question with only numbers",
+ "4?",
+ "Sure.",
+ },
+ {
+ "shouting with special characters",
+ "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!",
+ "Whoa, chill out!",
+ },
+ {
+ "shouting with umlauts",
+ "ÜMLÄÜTS!",
+ "Whoa, chill out!",
+ },
+ {
+ "calmly speaking with umlauts",
+ "ÜMLäÜTS!",
+ "Whatever.",
+ },
+ {
+ "shouting with no exclamation mark",
+ "I HATE YOU",
+ "Whoa, chill out!",
+ },
+ {
+ "statement containing question mark",
+ "Ending with ? means a question.",
+ "Whatever.",
+ },
+ {
+ "non-letters with question",
+ ":) ?",
+ "Sure.",
+ },
+ {
+ "prattling on",
+ "Wait! Hang on. Are you going to be OK?",
+ "Sure.",
+ },
+ {
+ "silence",
+ "",
+ "Fine. Be that way!",
+ },
+ {
+ "prolonged silence",
+ " ",
+ "Fine. Be that way!",
+ },
+ {
+ "alternate silence",
+ "\t\t\t\t\t\t\t\t\t\t",
+ "Fine. Be that way!",
+ },
+ {
+ "multiple line question",
+ "\nDoes this cryogenic chamber make me look fat?\nno",
+ "Whatever.",
+ },
+ {
+ "starting with whitespace",
+ " hmmmmmmm...",
+ "Whatever.",
+ },
+ {
+ "ending with whitespace",
+ "Okay if like my spacebar quite a bit? ",
+ "Sure.",
+ },
+ {
+ "other whitespace",
+ "\n\r \t\v\u00a0\u2002",
+ "Fine. Be that way!",
+ },
+}
diff --git a/go/clock/README.md b/go/clock/README.md
new file mode 100644
index 0000000..84f1f51
--- /dev/null
+++ b/go/clock/README.md
@@ -0,0 +1,27 @@
+# Clock
+
+Implement a clock that handles times without dates.
+
+Create a clock that is independent of date.
+
+You should be able to add and subtract minutes to it.
+
+Two clocks that represent the same time should be equal to each other.
+
+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
+
+Pairing session with Erin Drummond [https://twitter.com/ebdrummond](https://twitter.com/ebdrummond)
+
+## 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/clock/cases_test.go b/go/clock/cases_test.go
new file mode 100644
index 0000000..3884510
--- /dev/null
+++ b/go/clock/cases_test.go
@@ -0,0 +1,152 @@
+package clock
+
+// Source: exercism/x-common
+// Commit: 180638f Merge pull request #217 from ErikSchierboom/patch-2
+
+// Test creating a new clock with an initial time.
+var timeTests = []struct {
+ h, m int
+ want string
+}{
+ {8, 0, "08:00"}, // on the hour
+ {11, 9, "11:09"}, // past the hour
+ {24, 0, "00:00"}, // midnight is zero hours
+ {25, 0, "01:00"}, // hour rolls over
+ {100, 0, "04:00"}, // hour rolls over continuously
+ {1, 60, "02:00"}, // sixty minutes is next hour
+ {0, 160, "02:40"}, // minutes roll over
+ {0, 1723, "04:43"}, // minutes roll over continuously
+ {25, 160, "03:40"}, // hour and minutes roll over
+ {201, 3001, "11:01"}, // hour and minutes roll over continuously
+ {72, 8640, "00:00"}, // hour and minutes roll over to exactly midnight
+ {-1, 15, "23:15"}, // negative hour
+ {-25, 0, "23:00"}, // negative hour rolls over
+ {-91, 0, "05:00"}, // negative hour rolls over continuously
+ {1, -40, "00:20"}, // negative minutes
+ {1, -160, "22:20"}, // negative minutes roll over
+ {1, -4820, "16:40"}, // negative minutes roll over continuously
+ {-25, -160, "20:20"}, // negative hour and minutes both roll over
+ {-121, -5810, "22:10"}, // negative hour and minutes both roll over continuously
+}
+
+// Test adding and subtracting minutes.
+var addTests = []struct {
+ h, m, a int
+ want string
+}{
+ {10, 0, 3, "10:03"}, // add minutes
+ {6, 41, 0, "06:41"}, // add no minutes
+ {0, 45, 40, "01:25"}, // add to next hour
+ {10, 0, 61, "11:01"}, // add more than one hour
+ {0, 45, 160, "03:25"}, // add more than two hours with carry
+ {23, 59, 2, "00:01"}, // add across midnight
+ {5, 32, 1500, "06:32"}, // add more than one day (1500 min = 25 hrs)
+ {1, 1, 3500, "11:21"}, // add more than two days
+ {10, 3, -3, "10:00"}, // subtract minutes
+ {10, 3, -30, "09:33"}, // subtract to previous hour
+ {10, 3, -70, "08:53"}, // subtract more than an hour
+ {0, 3, -4, "23:59"}, // subtract across midnight
+ {0, 0, -160, "21:20"}, // subtract more than two hours
+ {6, 15, -160, "03:35"}, // subtract more than two hours with borrow
+ {5, 32, -1500, "04:32"}, // subtract more than one day (1500 min = 25 hrs)
+ {2, 20, -3000, "00:20"}, // subtract more than two days
+}
+
+// Construct two separate clocks, set times, test if they are equal.
+type hm struct{ h, m int }
+
+var eqTests = []struct {
+ c1, c2 hm
+ want bool
+}{
+ // clocks with same time
+ {
+ hm{15, 37},
+ hm{15, 37},
+ true,
+ },
+ // clocks a minute apart
+ {
+ hm{15, 36},
+ hm{15, 37},
+ false,
+ },
+ // clocks an hour apart
+ {
+ hm{14, 37},
+ hm{15, 37},
+ false,
+ },
+ // clocks with hour overflow
+ {
+ hm{10, 37},
+ hm{34, 37},
+ true,
+ },
+ // clocks with hour overflow by several days
+ {
+ hm{3, 11},
+ hm{99, 11},
+ true,
+ },
+ // clocks with negative hour
+ {
+ hm{22, 40},
+ hm{-2, 40},
+ true,
+ },
+ // clocks with negative hour that wraps
+ {
+ hm{17, 3},
+ hm{-31, 3},
+ true,
+ },
+ // clocks with negative hour that wraps multiple times
+ {
+ hm{13, 49},
+ hm{-83, 49},
+ true,
+ },
+ // clocks with minute overflow
+ {
+ hm{0, 1},
+ hm{0, 1441},
+ true,
+ },
+ // clocks with minute overflow by several days
+ {
+ hm{2, 2},
+ hm{2, 4322},
+ true,
+ },
+ // clocks with negative minute
+ {
+ hm{2, 40},
+ hm{3, -20},
+ true,
+ },
+ // clocks with negative minute that wraps
+ {
+ hm{4, 10},
+ hm{5, -1490},
+ true,
+ },
+ // clocks with negative minute that wraps multiple times
+ {
+ hm{6, 15},
+ hm{6, -4305},
+ true,
+ },
+ // clocks with negative hours and minutes
+ {
+ hm{7, 32},
+ hm{-12, -268},
+ true,
+ },
+ // clocks with negative hours and minutes that wrap
+ {
+ hm{18, 7},
+ hm{-54, -11513},
+ true,
+ },
+}
diff --git a/go/clock/clock.go b/go/clock/clock.go
new file mode 100644
index 0000000..036a69b
--- /dev/null
+++ b/go/clock/clock.go
@@ -0,0 +1,29 @@
+package clock
+
+import "fmt"
+
+const testVersion = 4
+
+type Clock struct {
+ hour, minute int
+}
+
+func New(hour, minute int) Clock {
+ for minute < 0 {
+ minute += 60
+ hour -= 1
+ }
+ hour += minute / 60
+ for hour < 0 {
+ hour += 24
+ }
+ return Clock{hour % 24, minute % 60}
+}
+
+func (c Clock) String() string {
+ return fmt.Sprintf("%02d:%02d", c.hour, c.minute)
+}
+
+func (c Clock) Add(minutes int) Clock {
+ return New(c.hour, c.minute+minutes)
+}
diff --git a/go/clock/clock_test.go b/go/clock/clock_test.go
new file mode 100644
index 0000000..7642c41
--- /dev/null
+++ b/go/clock/clock_test.go
@@ -0,0 +1,83 @@
+package clock
+
+import (
+ "reflect"
+ "testing"
+)
+
+// Clock type API:
+//
+// New(hour, minute int) Clock // a "constructor"
+// (Clock) String() string // a "stringer"
+// (Clock) Add(minutes int) Clock
+//
+// The Add method should also handle subtraction by accepting negative values.
+// To satisfy the readme requirement about clocks being equal, values of
+// your Clock type need to work with the == operator.
+//
+// It might help to study the time.Time type in the standard library
+// (https://golang.org/pkg/time/#Time) as a model. See how constructors there
+// (Date and Now) return Time values rather than pointers. Note also how
+// most time.Time methods have value receivers rather than pointer receivers.
+// For more background on this read
+// https://github.com/golang/go/wiki/CodeReviewComments#receiver-type.
+
+const targetTestVersion = 4
+
+func TestCreateClock(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
+ }
+ for _, n := range timeTests {
+ if got := New(n.h, n.m); got.String() != n.want {
+ t.Fatalf("New(%d, %d) = %q, want %q", n.h, n.m, got, n.want)
+ }
+ }
+ t.Log(len(timeTests), "test cases")
+}
+
+func TestAddMinutes(t *testing.T) {
+ for _, a := range addTests {
+ if got := New(a.h, a.m).Add(a.a); got.String() != a.want {
+ t.Fatalf("New(%d, %d).Add(%d) = %q, want %q",
+ a.h, a.m, a.a, got, a.want)
+ }
+ }
+ t.Log(len(addTests), "test cases")
+}
+
+func TestCompareClocks(t *testing.T) {
+ for _, e := range eqTests {
+ clock1 := New(e.c1.h, e.c1.m)
+ clock2 := New(e.c2.h, e.c2.m)
+ got := clock1 == clock2
+ if got != e.want {
+ t.Log("Clock1:", clock1)
+ t.Log("Clock2:", clock2)
+ t.Logf("Clock1 == Clock2 is %t, want %t", got, e.want)
+ if reflect.DeepEqual(clock1, clock2) {
+ t.Log("(Hint: see comments in clock_test.go.)")
+ }
+ t.FailNow()
+ }
+ }
+ t.Log(len(eqTests), "test cases")
+}
+
+func BenchmarkAddMinutes(b *testing.B) {
+ c := New(12, 0)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ for _, a := range addTests {
+ c.Add(a.a)
+ }
+ }
+}
+
+func BenchmarkCreateClocks(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, n := range timeTests {
+ New(n.h, n.m)
+ }
+ }
+}
diff --git a/go/gigasecond/README.md b/go/gigasecond/README.md
new file mode 100644
index 0000000..788f4c0
--- /dev/null
+++ b/go/gigasecond/README.md
@@ -0,0 +1,23 @@
+# Gigasecond
+
+Write a program that calculates the moment when someone has lived for 10^9 seconds.
+
+A gigasecond is 10^9 (1,000,000,000) seconds.
+
+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
+
+Chapter 9 in Chris Pine's online Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=09](http://pine.fm/LearnToProgram/?Chapter=09)
+
+## 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/gigasecond/cases_test.go b/go/gigasecond/cases_test.go
new file mode 100644
index 0000000..520101b
--- /dev/null
+++ b/go/gigasecond/cases_test.go
@@ -0,0 +1,31 @@
+package gigasecond
+
+// Source: exercism/x-common
+// Commit: 1e9e232 Merge pull request #45 from soniakeys/gigasecond-tests
+
+// Add one gigasecond to the input.
+var addCases = []struct {
+ in string
+ want string
+}{
+ {
+ "2011-04-25",
+ "2043-01-01T01:46:40",
+ },
+ {
+ "1977-06-13",
+ "2009-02-19T01:46:40",
+ },
+ {
+ "1959-07-19",
+ "1991-03-27T01:46:40",
+ },
+ {
+ "2015-01-24T22:00:00",
+ "2046-10-02T23:46:40",
+ },
+ {
+ "2015-01-24T23:59:59",
+ "2046-10-03T01:46:39",
+ },
+}
diff --git a/go/gigasecond/gigasecond.go b/go/gigasecond/gigasecond.go
new file mode 100644
index 0000000..dd3f310
--- /dev/null
+++ b/go/gigasecond/gigasecond.go
@@ -0,0 +1,9 @@
+package gigasecond
+
+import "time"
+
+const testVersion = 4
+
+func AddGigasecond(t time.Time) time.Time {
+ return t.Add(1e9 * time.Second)
+}
diff --git a/go/gigasecond/gigasecond_test.go b/go/gigasecond/gigasecond_test.go
new file mode 100644
index 0000000..96642cf
--- /dev/null
+++ b/go/gigasecond/gigasecond_test.go
@@ -0,0 +1,63 @@
+package gigasecond
+
+// Write a function AddGigasecond that works with time.Time.
+// Also define a variable Birthday set to your (or someone else's) birthday.
+// Run go test -v to see your gigasecond anniversary.
+
+import (
+ "os"
+ "testing"
+ "time"
+)
+
+const targetTestVersion = 4
+
+// date formats used in test data
+const (
+ fmtD = "2006-01-02"
+ fmtDT = "2006-01-02T15:04:05"
+)
+
+func TestAddGigasecond(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
+ }
+ for _, tc := range addCases {
+ in := parse(tc.in, t)
+ want := parse(tc.want, t)
+ got := AddGigasecond(in)
+ if !got.Equal(want) {
+ t.Fatalf(`AddGigasecond(%s)
+ = %s
+want %s`, in, got, want)
+ }
+ }
+ t.Log("Tested", len(addCases), "cases.")
+}
+
+func parse(s string, t *testing.T) time.Time {
+ tt, err := time.Parse(fmtDT, s) // try full date time format first
+ if err != nil {
+ tt, err = time.Parse(fmtD, s) // also allow just date
+ }
+ if err != nil {
+ // can't run tests if input won't parse. if this seems to be a
+ // development or ci environment, raise an error. if this condition
+ // makes it to the solver though, ask for a bug report.
+ _, statErr := os.Stat("example_gen.go")
+ if statErr == nil || os.Getenv("TRAVIS_GO_VERSION") > "" {
+ t.Fatal(err)
+ } else {
+ t.Log(err)
+ t.Skip("(Not your problem. " +
+ "please file issue at https://github.com/exercism/xgo.)")
+ }
+ }
+ return tt
+}
+
+func BenchmarkAddGigasecond(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ AddGigasecond(time.Time{})
+ }
+}
diff --git a/go/hamming/README.md b/go/hamming/README.md
new file mode 100644
index 0000000..83c017d
--- /dev/null
+++ b/go/hamming/README.md
@@ -0,0 +1,54 @@
+# Hamming
+
+Write a program that can calculate the Hamming difference between two DNA strands.
+
+A mutation is simply a mistake that occurs during the creation or
+copying of a nucleic acid, in particular DNA. Because nucleic acids are
+vital to cellular functions, mutations tend to cause a ripple effect
+throughout the cell. Although mutations are technically mistakes, a very
+rare mutation may equip the cell with a beneficial attribute. In fact,
+the macro effects of evolution are attributable by the accumulated
+result of beneficial microscopic mutations over many generations.
+
+The simplest and most common type of nucleic acid mutation is a point
+mutation, which replaces one base with another at a single nucleotide.
+
+By counting the number of differences between two homologous DNA strands
+taken from different genomes with a common ancestor, we get a measure of
+the minimum number of point mutations that could have occurred on the
+evolutionary path between the two strands.
+
+This is called the 'Hamming distance'.
+
+It is found by comparing two DNA strands and counting how many of the
+nucleotides are different from their equivalent in the other string.
+
+ GAGCCTACTAACGGGAT
+ CATCGTAATGACGGCCT
+ ^ ^ ^ ^ ^ ^^
+
+The Hamming distance between these two DNA strands is 7.
+
+# Implementation notes
+
+The Hamming distance is only defined for sequences of equal length. This means
+that based on the definition, each language could deal with getting sequences
+of equal length differently.
+
+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
+
+The Calculating Point Mutations problem at Rosalind [http://rosalind.info/problems/hamm/](http://rosalind.info/problems/hamm/)
+
+## 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/hamming/cases_test.go b/go/hamming/cases_test.go
new file mode 100644
index 0000000..fc808b5
--- /dev/null
+++ b/go/hamming/cases_test.go
@@ -0,0 +1,81 @@
+package hamming
+
+// Source: exercism/x-common
+// Commit: c84e435 Merge pull request #51 from soniakeys/master
+
+var testCases = []struct {
+ s1 string
+ s2 string
+ want int
+}{
+ { // identical strands
+ "A",
+ "A",
+ 0,
+ },
+ { // long identical strands
+ "GGACTGA",
+ "GGACTGA",
+ 0,
+ },
+ { // complete distance in single nucleotide strands
+ "A",
+ "G",
+ 1,
+ },
+ { // complete distance in small strands
+ "AG",
+ "CT",
+ 2,
+ },
+ { // small distance in small strands
+ "AT",
+ "CT",
+ 1,
+ },
+ { // small distance
+ "GGACG",
+ "GGTCG",
+ 1,
+ },
+ { // small distance in long strands
+ "ACCAGGG",
+ "ACTATGG",
+ 2,
+ },
+ { // non-unique character in first strand
+ "AGA",
+ "AGG",
+ 1,
+ },
+ { // non-unique character in second strand
+ "AGG",
+ "AGA",
+ 1,
+ },
+ { // large distance
+ "GATACA",
+ "GCATAA",
+ 4,
+ },
+ { // large distance in off-by-one strand
+ "GGACGGATTCTG",
+ "AGGACGGATTCT",
+ 9,
+ },
+ { // empty strands
+ "",
+ "",
+ 0,
+ },
+ { // disallow first strand longer
+ "AATG",
+ "AAA",
+ -1,
+ },
+ { // disallow second strand longer
+ "ATA",
+ "AGTG",
+ -1,
+ },
+}
diff --git a/go/hamming/hamming.go b/go/hamming/hamming.go
new file mode 100644
index 0000000..88dca1e
--- /dev/null
+++ b/go/hamming/hamming.go
@@ -0,0 +1,18 @@
+package hamming
+
+import "errors"
+
+const testVersion = 4
+
+func Distance(a, b string) (int, error) {
+ if len(a) != len(b) {
+ return 0, errors.New("same length required")
+ }
+ var n int
+ for i := 0; i < len(a); i++ {
+ if a[i] != b[i] {
+ n++
+ }
+ }
+ return n, nil
+}
diff --git a/go/hamming/hamming_test.go b/go/hamming/hamming_test.go
new file mode 100644
index 0000000..bfee705
--- /dev/null
+++ b/go/hamming/hamming_test.go
@@ -0,0 +1,36 @@
+package hamming
+
+import "testing"
+
+const targetTestVersion = 4
+
+func TestHamming(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
+ }
+ for _, tc := range testCases {
+ switch got, err := Distance(tc.s1, tc.s2); {
+ case err != nil:
+ var _ error = err
+ if tc.want >= 0 {
+ t.Fatalf("Distance(%q, %q) returned error: %v",
+ tc.s1, tc.s2, err)
+ }
+ case tc.want < 0:
+ t.Fatalf("Distance(%q, %q) = %d. Expected error.",
+ tc.s1, tc.s2, got)
+ case 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 {
+ 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..42aa266
--- /dev/null
+++ b/go/hello-world/README.md
@@ -0,0 +1,58 @@
+# Hello World
+
+Write a function that greets the user by name, or by saying "Hello, World!" if no name is given.
+
+["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
+
+**Note:** You can skip this exercise by running:
+
+ exercism skip $LANGUAGE hello-world
+
+## Specification
+
+Write a `Hello World!` function that can greet someone given their name.
+The function should return the appropriate greeting.
+
+For an input of "Alice", the response should be "Hello, Alice!".
+
+If a name is not given, the response should be "Hello, World!"
+
+## Test-Driven Development
+
+As programmers mature, they eventually want to test their code.
+
+Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
+
+It will also provide you with a safety net to explore other solutions without breaking the functionality.
+
+### A typical TDD workflow on Exercism:
+
+1. Run the test file and pick one test that's failing.
+2. Write some code to fix the test you picked.
+3. Re-run the tests to confirm the test is now passing.
+4. Repeat from step 1.
+5. Submit your solution (`exercism submit /path/to/file`)
+
+## Instructions
+
+Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
+
+It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
+
+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
+
+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 Problems
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.
+
diff --git a/go/hello-world/hello_test.go b/go/hello-world/hello_test.go
new file mode 100644
index 0000000..3099d41
--- /dev/null
+++ b/go/hello-world/hello_test.go
@@ -0,0 +1,29 @@
+package hello
+
+import "testing"
+
+// Define a function HelloWorld(string) string.
+//
+// Also define a testVersion with a value that matches
+// the targetTestVersion here.
+
+const targetTestVersion = 2
+
+func TestHelloWorld(t *testing.T) {
+ tests := []struct {
+ name, expected string
+ }{
+ {"", "Hello, World!"},
+ {"Gopher", "Hello, Gopher!"},
+ }
+ for _, test := range tests {
+ observed := HelloWorld(test.name)
+ if observed != test.expected {
+ t.Fatalf("HelloWorld(%s) = %v, want %v", test.name, observed, test.expected)
+ }
+ }
+
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
+ }
+}
diff --git a/go/hello-world/hello_world.go b/go/hello-world/hello_world.go
new file mode 100644
index 0000000..590df4e
--- /dev/null
+++ b/go/hello-world/hello_world.go
@@ -0,0 +1,11 @@
+package hello
+
+const testVersion = 2
+
+// HelloWorld greets the World
+func HelloWorld(s string) string {
+ if s == "" {
+ s = "World"
+ }
+ return "Hello, " + s + "!"
+}
diff --git a/go/leap/README.md b/go/leap/README.md
new file mode 100644
index 0000000..9205866
--- /dev/null
+++ b/go/leap/README.md
@@ -0,0 +1,45 @@
+# Leap
+
+Write a program that will take a year and report if it is a leap year.
+
+The tricky thing here is that a leap year in the Gregorian calendar occurs:
+
+```plain
+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.
+
+If your language provides a method in the standard library that does
+this look-up, pretend it doesn't exist and implement it yourself.
+
+## 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
+
+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 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.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/leap/cases_test.go b/go/leap/cases_test.go
new file mode 100644
index 0000000..d1af40f
--- /dev/null
+++ b/go/leap/cases_test.go
@@ -0,0 +1,17 @@
+package leap
+
+// Source: exercism/x-common
+// Commit: 945d08e Merge pull request #50 from soniakeys/master
+
+var testCases = []struct {
+ year int
+ expected bool
+ description string
+}{
+ {1996, true, "leap year"},
+ {1997, false, "non-leap year"},
+ {1998, false, "non-leap even year"},
+ {1900, false, "century"},
+ {2400, true, "fourth century"},
+ {2000, true, "Y2K"},
+}
diff --git a/go/leap/leap.go b/go/leap/leap.go
new file mode 100644
index 0000000..75908eb
--- /dev/null
+++ b/go/leap/leap.go
@@ -0,0 +1,8 @@
+package leap
+
+const testVersion = 2
+
+// IsLeapYear reports if it year is a leap year
+func IsLeapYear(y int) bool {
+ return y%4 == 0 && y%100 != 0 || y%400 == 0
+}
diff --git a/go/leap/leap_test.go b/go/leap/leap_test.go
new file mode 100644
index 0000000..974d79e
--- /dev/null
+++ b/go/leap/leap_test.go
@@ -0,0 +1,32 @@
+package leap
+
+import "testing"
+
+// Define a function IsLeapYear(int) bool.
+//
+// Also define a testVersion with a value that matches
+// the targetTestVersion here.
+
+const targetTestVersion = 2
+
+func TestLeapYears(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
+ }
+ 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/raindrops/README.md b/go/raindrops/README.md
new file mode 100644
index 0000000..7cd1285
--- /dev/null
+++ b/go/raindrops/README.md
@@ -0,0 +1,37 @@
+# Raindrops
+
+Write a program that converts a number to a string, the contents of which depends on the number's factors.
+
+- If the number contains 3 as a factor, output 'Pling'.
+- If the number contains 5 as a factor, output 'Plang'.
+- If the number contains 7 as a factor, output 'Plong'.
+- If the number does not contain 3, 5, or 7 as a factor,
+ just pass the number's digits straight through.
+
+## Examples
+
+- 28's prime-factorization is 2, 2, 7.
+ - In raindrop-speak, this would be a simple "Plong".
+- 1755 prime-factorization is 3, 3, 3, 5, 13.
+ - In raindrop-speak, this would be a "PlingPlang".
+- The prime factors of 34 are 2 and 17.
+ - Raindrop-speak doesn't know what to make of that,
+ so it just goes with the straightforward "34".
+
+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 variation on a famous interview question intended to weed out potential candidates. [http://jumpstartlab.com](http://jumpstartlab.com)
+
+## 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/raindrops/cases_test.go b/go/raindrops/cases_test.go
new file mode 100644
index 0000000..e551032
--- /dev/null
+++ b/go/raindrops/cases_test.go
@@ -0,0 +1,25 @@
+package raindrops
+
+// Source: exercism/x-common
+// Commit: 3b07e53 Merge pull request #117 from mikeyjcat/add-raindrops-json
+
+var tests = []struct {
+ input int
+ expected string
+}{
+ {1, "1"},
+ {3, "Pling"},
+ {5, "Plang"},
+ {7, "Plong"},
+ {6, "Pling"},
+ {9, "Pling"},
+ {10, "Plang"},
+ {14, "Plong"},
+ {15, "PlingPlang"},
+ {21, "PlingPlong"},
+ {25, "Plang"},
+ {35, "PlangPlong"},
+ {49, "Plong"},
+ {52, "52"},
+ {105, "PlingPlangPlong"},
+}
diff --git a/go/raindrops/raindrops.go b/go/raindrops/raindrops.go
new file mode 100644
index 0000000..d692900
--- /dev/null
+++ b/go/raindrops/raindrops.go
@@ -0,0 +1,21 @@
+package raindrops
+
+import "fmt"
+
+const testVersion = 2
+
+func Convert(n int) (s string) {
+ if n%3 == 0 {
+ s += "Pling"
+ }
+ if n%5 == 0 {
+ s += "Plang"
+ }
+ if n%7 == 0 {
+ s += "Plong"
+ }
+ if s == "" {
+ s = fmt.Sprint(n)
+ }
+ return
+}
diff --git a/go/raindrops/raindrops_test.go b/go/raindrops/raindrops_test.go
new file mode 100644
index 0000000..befa699
--- /dev/null
+++ b/go/raindrops/raindrops_test.go
@@ -0,0 +1,25 @@
+package raindrops
+
+import "testing"
+
+const targetTestVersion = 2
+
+func TestConvert(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
+ }
+ 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/triangle/.triangle.go.swp b/go/triangle/.triangle.go.swp
new file mode 100644
index 0000000..d58a2a8
--- /dev/null
+++ b/go/triangle/.triangle.go.swp
Binary files differ
diff --git a/go/triangle/README.md b/go/triangle/README.md
new file mode 100644
index 0000000..8f1485d
--- /dev/null
+++ b/go/triangle/README.md
@@ -0,0 +1,29 @@
+# Triangle
+
+Write a program that can tell you if a triangle is equilateral, isosceles, or scalene.
+
+The program should raise an error if the triangle cannot exist.
+
+## Hint
+
+The sum of the lengths of any two sides of a triangle always exceeds or
+is equal to the length of the third side, a principle known as the _triangle
+inequality_.
+
+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
+
+The Ruby Koans triangle project, parts 1 & 2 [http://rubykoans.com](http://rubykoans.com)
+
+## 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/triangle/triangle.go b/go/triangle/triangle.go
new file mode 100644
index 0000000..7243375
--- /dev/null
+++ b/go/triangle/triangle.go
@@ -0,0 +1,17 @@
+package triangle
+
+const testVersion = 2
+
+// Code this function.
+func KindFromSides(a, b, c float64) Kind
+
+// Notice it returns this type. Pick something suitable.
+type Kind
+
+// Pick values for the following identifiers used by the test program.
+NaT // not a triangle
+Equ // equilateral
+Iso // isosceles
+Sca // scalene
+
+// Organize your code for readability.
diff --git a/go/triangle/triangle_test.go b/go/triangle/triangle_test.go
new file mode 100644
index 0000000..4532389
--- /dev/null
+++ b/go/triangle/triangle_test.go
@@ -0,0 +1,99 @@
+package triangle
+
+import (
+ "math"
+ "testing"
+)
+
+const targetTestVersion = 2
+
+type testCase struct {
+ want Kind
+ a, b, c float64
+}
+
+// basic test cases
+var testData = []testCase{
+ {Equ, 2, 2, 2}, // same length
+ {Equ, 10, 10, 10}, // a little bigger
+ {Iso, 3, 4, 4}, // last two sides equal
+ {Iso, 4, 3, 4}, // first and last sides equal
+ {Iso, 4, 4, 3}, // first two sides equal
+ {Iso, 10, 10, 2}, // again
+ {Iso, 2, 4, 2}, // a "triangle" that is just a line is still OK
+ {Sca, 3, 4, 5}, // no sides equal
+ {Sca, 10, 11, 12}, // again
+ {Sca, 5, 4, 2}, // descending order
+ {Sca, .4, .6, .3}, // small sides
+ {Sca, 1, 4, 3}, // a "triangle" that is just a line is still OK
+ {NaT, 0, 0, 0}, // zero length
+ {NaT, 3, 4, -5}, // negative length
+ {NaT, 1, 1, 3}, // fails triangle inequality
+ {NaT, 2, 5, 2}, // another
+ {NaT, 7, 3, 2}, // another
+}
+
+// generate cases with NaN and Infs, append to basic cases
+func init() {
+ nan := math.NaN()
+ pinf := math.Inf(1)
+ ninf := math.Inf(-1)
+ nf := make([]testCase, 4*4*4)
+ i := 0
+ for _, a := range []float64{3, nan, pinf, ninf} {
+ for _, b := range []float64{4, nan, pinf, ninf} {
+ for _, c := range []float64{5, nan, pinf, ninf} {
+ nf[i] = testCase{NaT, a, b, c}
+ i++
+ }
+ }
+ }
+ testData = append(testData, nf[1:]...)
+}
+
+// Test that the kinds are not equal to each other.
+// If they are equal, then TestKind will return false positives.
+func TestKindsNotEqual(t *testing.T) {
+ kindsAndNames := []struct {
+ kind Kind
+ name string
+ }{
+ {Equ, "Equ"},
+ {Iso, "Iso"},
+ {Sca, "Sca"},
+ {NaT, "NaT"},
+ }
+
+ for i, pair1 := range kindsAndNames {
+ for j := i + 1; j < len(kindsAndNames); j++ {
+ pair2 := kindsAndNames[j]
+ if pair1.kind == pair2.kind {
+ t.Fatalf("%s should not be equal to %s", pair1.name, pair2.name)
+ }
+ }
+ }
+}
+
+func TestKind(t *testing.T) {
+ for _, test := range testData {
+ got := KindFromSides(test.a, test.b, test.c)
+ if got != test.want {
+ t.Fatalf("Triangle with sides, %g, %g, %g = %v, want %v",
+ test.a, test.b, test.c, got, test.want)
+ }
+ }
+}
+
+func TestTestVersion(t *testing.T) {
+ if testVersion != targetTestVersion {
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
+ }
+}
+
+func BenchmarkKind(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, test := range testData {
+ KindFromSides(test.a, test.b, test.c)
+ }
+ }
+}