Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 205
Good morning! Here's your coding interview problem for today.

This problem was asked by IBM.

Given an integer, find the next permutation of it in absolute order. For example, given 48975, the next permutation would be 49578.

Pull request:
Day205
Resolves #423.

Patch:
diff --git a/README.md b/README.md
index 45be3b1..1d6ba77 100644
--- a/README.md
+++ b/README.md
@@ -215,6 +215,7 @@ problems from
 * [Day 202](https://github.com/vaskoz/dailycodingproblem-go/issues/417)
 * [Day 203](https://github.com/vaskoz/dailycodingproblem-go/issues/419)
 * [Day 204](https://github.com/vaskoz/dailycodingproblem-go/issues/421)
+* [Day 205](https://github.com/vaskoz/dailycodingproblem-go/issues/423)
 * [Day 206](https://github.com/vaskoz/dailycodingproblem-go/issues/424)
 * [Day 207](https://github.com/vaskoz/dailycodingproblem-go/issues/426)
 * [Day 208](https://github.com/vaskoz/dailycodingproblem-go/issues/427)
diff --git a/day205/problem.go b/day205/problem.go
new file mode 100644
index 0000000..7d75a0c
--- /dev/null
+++ b/day205/problem.go
@@ -0,0 +1,63 @@
+package day205
+
+import (
+	"errors"
+	"sort"
+)
+
+var errNoGreaterPermutation = errors.New("greater permutation impossible")
+
+// ErrNoGreaterPermutation is the error when the greater
+// permutation doesn't exist.
+func ErrNoGreaterPermutation() error {
+	return errNoGreaterPermutation
+}
+
+// NextPermutationUint find the next greater permutation
+// of it's digits in absolute order.
+// Return an error if a greater permutation isn't possible.
+func NextPermutationUint(num uint) (uint, error) {
+	digits := separateDigits(num)
+	var i int
+	for i = len(digits) - 1; i > 0; i-- {
+		if digits[i] > digits[i-1] {
+			break
+		}
+	}
+	if i == 0 {
+		sort.Ints(digits)
+		return 0, ErrNoGreaterPermutation()
+	}
+	x := digits[i-1]
+	min := i
+	for j := i + 1; j < len(digits); j++ {
+		if digits[j] > x && digits[j] < digits[min] {
+			min = j
+		}
+	}
+	digits[i-1], digits[min] = digits[min], digits[i-1]
+	sort.Ints(digits[i:])
+	return convertToUint(digits), nil
+}
+
+func convertToUint(digits []int) uint {
+	var result uint
+	multiplier := 1
+	for i := range digits {
+		result += uint(digits[len(digits)-1-i] * multiplier)
+		multiplier *= 10
+	}
+	return result
+}
+
+func separateDigits(num uint) []int {
+	var result []int
+	for num != 0 {
+		result = append(result, int(num)%10)
+		num /= 10
+	}
+	for i := 0; i < len(result)/2; i++ {
+		result[i], result[len(result)-1-i] = result[len(result)-1-i], result[i]
+	}
+	return result
+}


Test patch:
diff --git a/day205/problem_test.go b/day205/problem_test.go
new file mode 100644
index 0000000..bc6a2db
--- /dev/null
+++ b/day205/problem_test.go
@@ -0,0 +1,32 @@
+package day205
+
+import (
+	"testing"
+)
+
+var testcases = []struct {
+	in  uint
+	out uint
+	err error
+}{
+	{123, 132, nil},
+	{132, 213, nil},
+	{321, 0, ErrNoGreaterPermutation()},
+}
+
+func TestNextPermutationUint(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result, err := NextPermutationUint(tc.in); result != tc.out || err != tc.err {
+			t.Errorf("Expected (%v,%v) got (%v,%v)", tc.out, tc.err, result, err)
+		}
+	}
+}
+
+func BenchmarkNextPermutationUint(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			NextPermutationUint(tc.in)
+		}
+	}
+}