commit dfa1d6630c35dd5810036207a0c7125121c11126 Author: jimi Date: Mon Mar 7 19:29:33 2016 -0600 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..099d8b8 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# 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. + +Tests are provided, delete one `skip` at a time. + +## Hint + +The sum of the lengths of any two sides of a triangle always exceeds 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 [view source](http://rubykoans.com) diff --git a/triangle.go b/triangle.go new file mode 100644 index 0000000..7243375 --- /dev/null +++ b/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/triangle_test.go b/triangle_test.go new file mode 100644 index 0000000..4532389 --- /dev/null +++ b/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) + } + } +}