Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 102
Good morning! Here's your coding interview problem for today.

This problem was asked by Lyft.

Given a list of integers and a number K, return which contiguous elements of the list sum to K.

For example, if the list is `[1, 2, 3, 4, 5]` and K is `9`, then it should return `[2, 3, 4]`.

Pull request description:
Day102fix
Misread the problem and forgot to add a negative value tolerant solution. This now resolves #214.

Patch:
diff --git a/day102/problem.go b/day102/problem.go
index 87170ba..0d17bee 100644
--- a/day102/problem.go
+++ b/day102/problem.go
@@ -17,13 +17,17 @@ func ContiguousSumBrute(nums []int, k int) []int {
 	return result
 }
 
-// ContiguousSumFaster uses a window to return the
+// ContiguousSumNonNegative uses a window to return the
 // contiguous subset that sums to K.
+// Can only tolerate non-negative values, panics otherwise.
 // Runtime is O(N) and O(1) space.
-func ContiguousSumFaster(nums []int, k int) []int {
+func ContiguousSumNonNegative(nums []int, k int) []int {
 	var result []int
 	var sum, begin int
 	for end := 0; end < len(nums); end++ {
+		if nums[end] < 0 {
+			panic("negative values aren't permitted")
+		}
 		sum += nums[end]
 		if sum == k {
 			result = nums[begin : end+1]
@@ -37,3 +41,26 @@ func ContiguousSumFaster(nums []int, k int) []int {
 	}
 	return result
 }
+
+// ContiguousSumNegatives returns the
+// contiguous subset that sums to K.
+// This implementation tolerates negative values.
+// Runtime is O(N) and O(N) space.
+func ContiguousSumNegatives(nums []int, k int) []int {
+	var result []int
+	var sum int
+	m := make(map[int]int)
+	for i := range nums {
+		sum += nums[i]
+		if sum-k == 0 {
+			result = nums[0 : i+1]
+			break
+		}
+		if start, found := m[sum-k]; found {
+			result = nums[start+1 : i+1]
+			break
+		}
+		m[sum] = i
+	}
+	return result
+}


Test patch:
diff --git a/day102/problem_test.go b/day102/problem_test.go
index f973aaf..04e90b9 100644
--- a/day102/problem_test.go
+++ b/day102/problem_test.go
@@ -5,7 +5,7 @@ import (
 	"testing"
 )
 
-var testcases = []struct {
+var nonNegativeTestcases = []struct {
 	input    []int
 	k        int
 	expected []int
@@ -18,9 +18,27 @@ var testcases = []struct {
 		49, []int{4, 5, 6, 7, 8, 9, 10}},
 }
 
+var negativeTestcases = []struct {
+	input    []int
+	k        int
+	expected []int
+}{
+	{[]int{-1, 2, 3, 4, 5}, 1, []int{-1, 2}},
+	{[]int{1, -2, 3, 4, 5}, 5, []int{-2, 3, 4}},
+	{[]int{1, 2, -3, 4, 5}, 6, []int{-3, 4, 5}},
+	{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+		15, 16, 17, 18, 19, 20, 21, 22, 23, -24, -25},
+		-49, []int{-24, -25}},
+}
+
 func TestContiguousSumBrute(t *testing.T) {
 	t.Parallel()
-	for _, tc := range testcases {
+	for _, tc := range nonNegativeTestcases {
+		if result := ContiguousSumBrute(tc.input, tc.k); !reflect.DeepEqual(tc.expected, result) {
+			t.Errorf("Expected %v got %v", tc.expected, result)
+		}
+	}
+	for _, tc := range negativeTestcases {
 		if result := ContiguousSumBrute(tc.input, tc.k); !reflect.DeepEqual(tc.expected, result) {
 			t.Errorf("Expected %v got %v", tc.expected, result)
 		}
@@ -29,25 +47,66 @@ func TestContiguousSumBrute(t *testing.T) {
 
 func BenchmarkContiguousSumBrute(b *testing.B) {
 	for i := 0; i < b.N; i++ {
-		for _, tc := range testcases {
+		for _, tc := range nonNegativeTestcases {
+			ContiguousSumBrute(tc.input, tc.k)
+		}
+		for _, tc := range negativeTestcases {
 			ContiguousSumBrute(tc.input, tc.k)
 		}
 	}
 }
 
-func TestContiguousSumFaster(t *testing.T) {
+func TestContiguousSumNonNegative(t *testing.T) {
 	t.Parallel()
-	for _, tc := range testcases {
-		if result := ContiguousSumFaster(tc.input, tc.k); !reflect.DeepEqual(tc.expected, result) {
+	for _, tc := range nonNegativeTestcases {
+		if result := ContiguousSumNonNegative(tc.input, tc.k); !reflect.DeepEqual(tc.expected, result) {
 			t.Errorf("Expected %v got %v", tc.expected, result)
 		}
 	}
 }
 
-func BenchmarkContiguousSumFaster(b *testing.B) {
+func TestContiguousSumNonNegativePanic(t *testing.T) {
+	t.Parallel()
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("Expected a panic from the negative input value")
+		}
+	}()
+	ContiguousSumNonNegative([]int{1, -2, 3}, 10)
+}
+
+func BenchmarkContiguousSumNonNegative(b *testing.B) {
 	for i := 0; i < b.N; i++ {
-		for _, tc := range testcases {
-			ContiguousSumFaster(tc.input, tc.k)
+		for _, tc := range nonNegativeTestcases {
+			ContiguousSumNonNegative(tc.input, tc.k)
+		}
+		for _, tc := range nonNegativeTestcases {
+			ContiguousSumNonNegative(tc.input, tc.k)
+		}
+	}
+}
+
+func TestContiguousSumNegatives(t *testing.T) {
+	t.Parallel()
+	for _, tc := range nonNegativeTestcases {
+		if result := ContiguousSumNegatives(tc.input, tc.k); !reflect.DeepEqual(tc.expected, result) {
+			t.Errorf("Expected %v got %v", tc.expected, result)
+		}
+	}
+	for _, tc := range negativeTestcases {
+		if result := ContiguousSumNegatives(tc.input, tc.k); !reflect.DeepEqual(tc.expected, result) {
+			t.Errorf("Expected %v got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkContiguousSumNegatives(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range nonNegativeTestcases {
+			ContiguousSumNegatives(tc.input, tc.k)
+		}
+		for _, tc := range negativeTestcases {
+			ContiguousSumNegatives(tc.input, tc.k)
 		}
 	}
 }