Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 347
Good morning! Here's your coding interview problem for today.

This problem was asked by Yahoo.

You are given a string of length `N` and a parameter `k`. The string can be manipulated by taking one of the first k letters and moving it to the end.

Write a program to determine the lexicographically smallest string that can be created after an unlimited number of moves.

For example, suppose we are given the string `daily` and `k = 1`. The best we can create in this case is `ailyd`.

Pull request description:
Day347
Resolves #689.

Patch:
diff --git a/README.md b/README.md
index 3e2ccd9..cce6a41 100644
--- a/README.md
+++ b/README.md
@@ -333,3 +333,4 @@ problems from
 * [Day 339](https://github.com/vaskoz/dailycodingproblem-go/issues/676)
 * [Day 340](https://github.com/vaskoz/dailycodingproblem-go/issues/679)
 * [Day 342](https://github.com/vaskoz/dailycodingproblem-go/issues/682)
+* [Day 347](https://github.com/vaskoz/dailycodingproblem-go/issues/689)
diff --git a/day347/problem.go b/day347/problem.go
new file mode 100644
index 0000000..1406ea9
--- /dev/null
+++ b/day347/problem.go
@@ -0,0 +1,26 @@
+package day347
+
+import "strings"
+
+// LexicographicallySmallest returns the lexicographically smallest
+// string that can be created after an unlimited number of moves
+func LexicographicallySmallest(str string, k int) string {
+	var sb strings.Builder
+	result := str
+	for len(str) > 0 {
+		smallest := rune(str[0])
+		smallestIndex := 0
+		for i, r := range str {
+			if i < k && r < smallest {
+				smallest = r
+				smallestIndex = i
+			}
+		}
+		str = str[:smallestIndex] + str[smallestIndex+1:]
+		sb.WriteString(string(smallest))
+		if candidate := str + sb.String(); candidate < result {
+			result = candidate
+		}
+	}
+	return result
+}


Test patch:
diff --git a/day347/problem_test.go b/day347/problem_test.go
new file mode 100644
index 0000000..f79ea99
--- /dev/null
+++ b/day347/problem_test.go
@@ -0,0 +1,31 @@
+package day347
+
+import "testing"
+
+// nolint
+var testcases = []struct {
+	str      string
+	k        int
+	expected string
+}{
+	{"daily", 1, "ailyd"},
+	{"gaurang", 3, "agangru"},
+	{"geeksforgeeks", 5, "eefggeekkorss"},
+}
+
+func TestLexicographicallySmallest(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := LexicographicallySmallest(tc.str, tc.k); result != tc.expected {
+			t.Errorf("Expected %v, got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkLexicographicallySmallest(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			LexicographicallySmallest(tc.str, tc.k)
+		}
+	}
+}