Skip to content

Commit

Permalink
Merge aa2f1cd into 560b7a8
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Mar 19, 2019
2 parents 560b7a8 + aa2f1cd commit ccd6cda
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
63 changes: 63 additions & 0 deletions day205/problem.go
Original file line number Diff line number Diff line change
@@ -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
}
32 changes: 32 additions & 0 deletions day205/problem_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
}

0 comments on commit ccd6cda

Please sign in to comment.