Hi,
I have this code https://play.golang.org/p/9o5TReZ7jT3
My idea was to generate all possible combinations pretty much this:
aaa
bbb
ccc
abb
acc
baa
bbb
bcc
caa
cbb
ccc
aba
abb
abc
you get the picture I think.
I got this solution but the objective is to simplify the solution without using channels if possible :
package main
import "fmt"
func GenerateCombinations(alphabet string, length int) <-chan string {
c := make(chan string)
go func(c chan string) {
defer close(c)
AddLetter(c, "", alphabet, length)
}(c)
return c
}
func AddLetter(c chan string, combo string, alphabet string, length int) {
if length <= 0 {
return
}
var newCombo string
for _, ch := range alphabet {
newCombo = combo + string(ch)
c <- newCombo
AddLetter(c, newCombo, alphabet, length-1)
}
}
func main() {
list := "abc"
for combination := range GenerateCombinations(list, 3) {
if len(combination) == 3 {
fmt.Println(combination)
}
}
fmt.Println("Done!")
}
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
The first time this came up I wrote code to generate general alphabet combinations as quickly as I could. The approach I used was a generator object that one calls to set the length and alphabet size, and a Next() function that is called repeatedly until it signals that all values have been generated. The values are handled in a slightly indirect way.
There are three use modes:
(a) Simply advance the internal state by calling Next() until done, this lets you count the number of solutions without looking at the details, as in some of the associated tests.
(b) Interpret the present state as an array of symbols from the user-supplied alphabet string in a reused array. In this case, there is no allocation or garbage during generation.
(c) Interpret the present state as a string, such simply creates a string. This is (b) plus string creation and GC overhead. It is about 2.6 to 3.1 times slower.
There are two modes of generation as well, ordered (“AA, AB, BB”) and unordered (“AA, AB, BA, BB”). From the original post here, clearly unordered is the desired mode. The speeds of this on my MacBook feel fast…
BenchmarkUnordered1-8 200000000 8.21 ns/op
BenchmarkUnordered2-8 50000000 32.3 ns/op
BenchmarkUnordered3-8 10000000 194 ns/op
BenchmarkUnordered4-8 1000000 1538 ns/op
BenchmarkUnordered5-8 100000 18404 ns/op
BenchmarkUnordered6-8 5000 255203 ns/op
BenchmarkUnordered7-8 300 4163767 ns/op
BenchmarkUnordered8-8 20 81721059 ns/op
BenchmarkUnordered9-8 1 1883039855 ns/op
BenchmarkUnorderedRate1-8 500000000 3.68 ns/op
BenchmarkUnorderedRate2-8 200000000 7.92 ns/op
BenchmarkUnorderedRate3-8 100000000 13.4 ns/op
BenchmarkUnorderedRate4-8 100000000 18.6 ns/op
BenchmarkUnorderedRate5-8 100000000 24.1 ns/op
BenchmarkUnorderedRate6-8 50000000 27.9 ns/op
BenchmarkUnorderedRate7-8 50000000 32.2 ns/op
BenchmarkUnorderedRate8-8 30000000 37.3 ns/op
BenchmarkUnorderedRate9-8 30000000 40.7 ns/op
…with speeds for s-symbol alphabets of lengths 1..s being low tens of nanoseconds per combination in array modes and ~3x that in string mode. This is no channel, no allocation or freeing, no GC needed, no recursion. Because it has tests and the code in separate files, it is not really a good go playground candidate. Sorry.
--
Whatever they wanted, we've put far more into answering it than than they have in responding. I sent my response taking time from the Farnborough Air Show, not wanting their concerns to go unaddressed. Disappointed to see no following reply to all the good advice from everyone here.
Whatever they wanted, we've put far more into answering it than than they have in responding. I sent my response taking time from the Farnborough Air Show, not wanting their concerns to go unaddressed. Disappointed to see no following reply to all the good advice from everyone here.
On Jul 15, 2016 6:25 PM, "'Paul Borman' via golang-nuts" <golan...@googlegroups.com> wrote:
It wasn't clear to me what the OP wanted. Did they just want to print them? Did they want to use them? For use, I think the channel is probably the most straightforward to use, but the OP didn't want any channels at all. The underlying array that slices refer to could also be made smaller, for example, set = "ab" and size = 3 can be satisfied with the underlying text of aaababbbaa. I didn't bother to try and figure out a general algorithm, however, I just did that one by hand.