-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcombinations.go
48 lines (40 loc) · 1.01 KB
/
combinations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Package combs provides generic functions for producing combinations and
// permutations from slices of any type.
package combs
// Creates a channel that returns all combinations of n items from the slice v.
func Combinations[T any](n int, v []T) <-chan []T {
ch := make(chan []T)
go func() {
prefix := []T{}
combinationsRecursor(prefix, n, v, ch)
close(ch)
}()
return ch
}
func combinationsRecursor[T any](prefix []T, n int, v []T, ch chan<- []T) {
if n == 1 {
for _, c := range v {
l := len(prefix)
result := make([]T, l+1)
copy(result, prefix)
result[l] = c
ch <- result
}
return
}
if n == len(v) {
result := make([]T, len(prefix)+len(v))
copy(result, prefix)
copy(result[len(prefix):], v)
ch <- result
return
}
l := len(prefix)
newPrefix := make([]T, l+1)
copy(newPrefix, prefix)
newPrefix[l] = v[0]
// combinations with this element
combinationsRecursor(newPrefix, n-1, v[1:], ch)
// combinations without this element
combinationsRecursor(prefix, n, v[1:], ch)
}