Skip to content

Commit e972edb

Browse files
authored
Merge pull request #95 from sir-gon/feature/problem0024
[REFACTOR] Problem 0024: better algorithm.
2 parents 4d9725e + 3b9c35d commit e972edb

File tree

2 files changed

+35
-52
lines changed

2 files changed

+35
-52
lines changed

src/problem0024.go

Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,63 +16,47 @@
1616
package projecteuler
1717

1818
import (
19+
"strings"
20+
1921
utils "gon.cl/projecteuler.net/src/utils"
2022
)
2123

22-
func lexicographicPermutationFind(elements []string, permutationToFind int) []string {
23-
// "inner global variables" to catch the results shared across recursive branch calls.
24-
var lastBranchCollector []string = []string{}
25-
var currentCycle = 0
26-
27-
// Initial values
28-
var initBranchCollector []string = []string{}
29-
30-
// Recursive way to compute permutations
31-
var computePermutations func(stopAtCycle int, inputElements []string, branchCollector []string)
32-
33-
computePermutations = func(stopAtCycle int, inputElements []string, branchCollector []string) {
34-
if currentCycle >= stopAtCycle {
35-
return
36-
}
37-
38-
for i := 0; i < len(inputElements); i++ {
39-
var rootElement = inputElements[i]
40-
var restOfElements []string = []string{}
41-
42-
utils.Debug("root element: %d -> %s", i, rootElement)
43-
44-
for j := 0; j < len(inputElements); j++ {
45-
if i != j {
46-
restOfElements = append(restOfElements, inputElements[j])
47-
}
48-
}
49-
50-
newBranchCollector := make([]string, len(branchCollector))
51-
copy(newBranchCollector, branchCollector)
52-
newBranchCollector = append(newBranchCollector, rootElement)
53-
54-
// finally...
55-
if len(restOfElements) > 0 {
56-
utils.Debug("REST: %+v", restOfElements)
57-
58-
computePermutations(stopAtCycle, restOfElements, newBranchCollector)
59-
} else {
60-
lastBranchCollector = newBranchCollector
61-
currentCycle += 1
24+
func factorial(n int) int {
25+
i := n
26+
out := 1
27+
for i > 1 {
28+
out *= i
29+
i -= 1
30+
}
31+
return out
32+
}
6233

63-
utils.Debug("FINISH BRANCH: %d -> %+v", currentCycle, lastBranchCollector)
64-
}
34+
func permute(symbols string, target int) string {
35+
choices := strings.Split(symbols, "")
36+
answer := ""
37+
min := 0
38+
39+
for len(choices) > 0 {
40+
index := 0
41+
combos := factorial(len(choices) - 1)
42+
min += combos
43+
for target > min {
44+
index += 1
45+
min += combos
6546
}
47+
answer += choices[index]
48+
copy(choices[index:], choices[index+1:])
49+
choices[len(choices)-1] = ""
50+
choices = choices[:len(choices)-1]
51+
min -= combos
6652
}
6753

68-
computePermutations(permutationToFind, elements, initBranchCollector)
69-
70-
return lastBranchCollector
54+
return answer
7155
}
7256

73-
func Problem0024(inputElements []string, inputPermutationToFind int) []string {
57+
func Problem0024(inputElements string, inputPermutationToFind int) string {
7458

75-
var permutationFound = lexicographicPermutationFind(inputElements, inputPermutationToFind)
59+
var permutationFound = permute(inputElements, inputPermutationToFind)
7660

7761
utils.Info("Problem0024 answer => %+v", permutationFound)
7862

src/problem0024_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@ package projecteuler
1717

1818
import (
1919
"fmt"
20-
"strings"
2120
"testing"
2221

2322
"github.com/stretchr/testify/assert"
2423
)
2524

2625
func TestProblem0024SmallCase(t *testing.T) {
2726

28-
expectedSolution := []string{"A", "D", "C", "B"}
29-
inputElements := strings.Split("ABCD", "")
27+
expectedSolution := "ADCB"
28+
inputElements := "ABCD"
3029
const inputPermutationToFind = 6
3130

3231
testname := fmt.Sprintf("Problem0024(%+v, %d) => %v \n", inputElements, inputPermutationToFind, expectedSolution)
@@ -39,8 +38,8 @@ func TestProblem0024SmallCase(t *testing.T) {
3938

4039
func TestProblem0024(t *testing.T) {
4140

42-
expectedSolution := []string{"2", "7", "8", "3", "9", "1", "5", "4", "6", "0"}
43-
inputElements := strings.Split("0123456789", "")
41+
expectedSolution := "2783915460"
42+
inputElements := "0123456789"
4443
const inputPermutationToFind = 1000000
4544

4645
testname := fmt.Sprintf("Problem0024(%+v, %d) => %v \n", inputElements, inputPermutationToFind, expectedSolution)

0 commit comments

Comments
 (0)