From 15b34b4ce1eb481905d5a4fb7b62bab31e24039b Mon Sep 17 00:00:00 2001 From: Erocs Date: Wed, 11 Jan 2017 22:57:29 -0800 Subject: [PATCH] [Go] Challenge 6 --- challenge_6/go/erocs/README.md | 17 ++++ .../go/erocs/src/challenge6/challenge6.go | 52 ++++++++++++ .../erocs/src/challenge6/challenge6_test.go | 84 +++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 challenge_6/go/erocs/README.md create mode 100644 challenge_6/go/erocs/src/challenge6/challenge6.go create mode 100644 challenge_6/go/erocs/src/challenge6/challenge6_test.go diff --git a/challenge_6/go/erocs/README.md b/challenge_6/go/erocs/README.md new file mode 100644 index 000000000..4c95f8425 --- /dev/null +++ b/challenge_6/go/erocs/README.md @@ -0,0 +1,17 @@ +# Challenge 6: Determine Ranges + +## 1. Solution Description + +Since the input slice will always be sorted, this code creates a new _Range_ +using the first number. Subsequent numbers that are a single integer larger then +the previous will update the _Range_'s End value to match. When the end of the +input slice or a non-consecutive value is encountered, the current _Range_ will +be appended to the result slice and a new _Range_ will be created using the +value. Single value _Range_s (ex. 1->1) are omitted from the result slice. + +## 2. Running Tests + +In bash in this directory: + + export GOPATH=`pwd` + go test challenge6 diff --git a/challenge_6/go/erocs/src/challenge6/challenge6.go b/challenge_6/go/erocs/src/challenge6/challenge6.go new file mode 100644 index 000000000..16e73f28f --- /dev/null +++ b/challenge_6/go/erocs/src/challenge6/challenge6.go @@ -0,0 +1,52 @@ +package challenge6 + +import "fmt" + +// Tracks the start and end points of a range of consecutive integers. +type Range struct { + Start int + End int +} + +// Creates a new range with Start and End equalling n. +func NewRange(n int) Range { + return Range{Start: n, End: n} +} + +func (r *Range) String() string { + return fmt.Sprintf("%d->%d", r.Start, r.End) +} + +type RangeSlice []Range + +func (rs RangeSlice) ToStrings() []string { + strs := make([]string, 0, len(rs)) + for _, r := range rs { + strs = append(strs, r.String()) + } + return strs +} + +// Determines all ranges of consecutive values within the sorted input slice, +// ints. Resulting ranges consist of two or more values. +func FindRanges(ints []int) RangeSlice { + if len(ints) <= 0 { + return RangeSlice([]Range{}) + } + ranges := make([]Range, 0, len(ints)/2) + r := NewRange(ints[0]) + for _, i := range ints[1:] { + if r.End+1 == i { + r.End = i + } else { + if r.Start != r.End { + ranges = append(ranges, r) + } + r = NewRange(i) + } + } + if r.Start != r.End { + ranges = append(ranges, r) + } + return RangeSlice(ranges) +} diff --git a/challenge_6/go/erocs/src/challenge6/challenge6_test.go b/challenge_6/go/erocs/src/challenge6/challenge6_test.go new file mode 100644 index 000000000..4ad5fc99e --- /dev/null +++ b/challenge_6/go/erocs/src/challenge6/challenge6_test.go @@ -0,0 +1,84 @@ +package challenge6 + +import ( + "strings" + "testing" +) + +// Call challenge6.FindRanges() on _ints_ and concatenate the ranges into a +// single string for comparison testing. +func FR(ints []int) string { + return strings.Join(FindRanges(ints).ToStrings(), " ") +} + +func TestEmpty(t *testing.T) { + ex := "" + r := FR([]int{}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +func TestSingleton(t *testing.T) { + ex := "" + r := FR([]int{1}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +func TestSimpleRange(t *testing.T) { + ex := "1->2" + r := FR([]int{1, 2}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +func TestNegativeRange(t *testing.T) { + ex := "-2->-1" + r := FR([]int{-2, -1}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +func TestLongRange(t *testing.T) { + ex := "1->20000" + c := 20000 + ints := make([]int, 0, c) + for i := 1; i <= c; i++ { + ints = append(ints, i) + } + r := FR(ints) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +// TestTwoRanges +func TestRR(t *testing.T) { + ex := "10->12 14->16" + r := FR([]int{10, 11, 12, 14, 15, 16}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +// TestSingletonRangeSingleton +func TestSRS(t *testing.T) { + ex := "4->6" + r := FR([]int{2, 4, 5, 6, 8}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +} + +// TestRangeSingletonRange +func TestRSR(t *testing.T) { + ex := "1->3 7->9" + r := FR([]int{1, 2, 3, 5, 7, 8, 9}) + if r != ex { + t.Error("Mismatch, expected:", ex, "received:", r) + } +}