Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 114
Good morning! Here's your coding interview problem for today.

This problem was asked by Facebook.

Given a string and a set of delimiters, reverse the words in the string while maintaining the relative order of the delimiters. For example, given "hello/world:here", return "here/world:hello"

Follow-up: Does your solution work for the following cases: "hello/world:here/", "hello//world:here"

Pull request description:
Day114
Resolves #237 .

Patch:
diff --git a/README.md b/README.md
index bb8bb2d..6616b77 100644
--- a/README.md
+++ b/README.md
@@ -121,3 +121,4 @@ problems from
 * [Day 109](https://github.com/vaskoz/dailycodingproblem-go/issues/229)
 * [Day 110](https://github.com/vaskoz/dailycodingproblem-go/issues/231)
 * [Day 111](https://github.com/vaskoz/dailycodingproblem-go/issues/232)
+* [Day 114](https://github.com/vaskoz/dailycodingproblem-go/issues/237)
diff --git a/day114/problem.go b/day114/problem.go
new file mode 100644
index 0000000..b98391f
--- /dev/null
+++ b/day114/problem.go
@@ -0,0 +1,38 @@
+package day114
+
+import "strings"
+
+// ReverseWordsMaintainDelimters reverses the words in the string
+// while maintaining the relative order of the delimiters
+// Works only with two delimiters "/" or ":"
+// Runs in O(N) time and requires O(N) extra space to construct the result.
+func ReverseWordsMaintainDelimters(str string) string {
+	var start, end int
+	var words []string
+	var delimiters []string
+	for end <= len(str) {
+		if end == len(str) {
+			if str[end-1] != ':' && str[end-1] != '/' {
+				words = append(words, str[start:end])
+			}
+			break
+		}
+		if str[end] == '/' || str[end] == ':' {
+			delimiters = append(delimiters, string(str[end]))
+			words = append(words, str[start:end])
+			start = end + 1
+		}
+		end++
+	}
+	for i := 0; i < len(words)/2; i++ {
+		words[i], words[len(words)-1-i] = words[len(words)-1-i], words[i]
+	}
+	var result []string
+	if len(delimiters) != len(words) {
+		delimiters = append([]string{""}, delimiters...)
+	}
+	for i := range words {
+		result = append(result, delimiters[i], words[i])
+	}
+	return strings.Join(result, "")
+}


Test patch:
diff --git a/day114/problem_test.go b/day114/problem_test.go
new file mode 100644
index 0000000..e56f5fc
--- /dev/null
+++ b/day114/problem_test.go
@@ -0,0 +1,29 @@
+package day114
+
+import "testing"
+
+var testcases = []struct {
+	input, expected string
+}{
+	{"hello/world:here", "here/world:hello"},
+	{"hello/world:here/", "/here:world/hello"},
+	{"hello//world:here", "here/world/:hello"},
+	{"/hello//world:here/", "/here/world/:hello/"},
+}
+
+func TestReverseWordsMaintainDelimters(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := ReverseWordsMaintainDelimters(tc.input); result != tc.expected {
+			t.Errorf("Expected %v got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkReverseWordsMaintainDelimters(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			ReverseWordsMaintainDelimters(tc.input)
+		}
+	}
+}