|
16 | 16 | package projecteuler
|
17 | 17 |
|
18 | 18 | import (
|
| 19 | + "strings" |
| 20 | + |
19 | 21 | utils "gon.cl/projecteuler.net/src/utils"
|
20 | 22 | )
|
21 | 23 |
|
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 | +} |
62 | 33 |
|
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 |
65 | 46 | }
|
| 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 |
66 | 52 | }
|
67 | 53 |
|
68 |
| - computePermutations(permutationToFind, elements, initBranchCollector) |
69 |
| - |
70 |
| - return lastBranchCollector |
| 54 | + return answer |
71 | 55 | }
|
72 | 56 |
|
73 |
| -func Problem0024(inputElements []string, inputPermutationToFind int) []string { |
| 57 | +func Problem0024(inputElements string, inputPermutationToFind int) string { |
74 | 58 |
|
75 |
| - var permutationFound = lexicographicPermutationFind(inputElements, inputPermutationToFind) |
| 59 | + var permutationFound = permute(inputElements, inputPermutationToFind) |
76 | 60 |
|
77 | 61 | utils.Info("Problem0024 answer => %+v", permutationFound)
|
78 | 62 |
|
|
0 commit comments