-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcombinatorics.go
48 lines (41 loc) · 1.2 KB
/
combinatorics.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 generics
import (
"github.com/zeroflucs-given/generics/filtering"
)
// IndexedItem is an item that is indexed
type IndexedItem[T any] struct {
Index int `json:"index"`
Item T `json:"item"`
}
// Combinations generates all combinations of the input objects at the specified size.
func Combinations[T any](items []T, size int) [][]T {
if size == 0 || size > len(items) {
return nil
}
var result [][]T
for i, item := range items {
if size == 1 {
result = append(result, []T{item})
} else {
rest := items[i+1:]
for _, comb := range Combinations(rest, size-1) {
result = append(result, append([]T{item}, comb...))
}
}
}
return result
}
// CombinationsFiltered returns the combinations of items, but applies a filter to the items. The returned indexed
// items represent the original positions in the raw list.
func CombinationsFiltered[T any](items []T, size int, filter filtering.Expression[T]) [][]IndexedItem[T] {
filteredItems := make([]IndexedItem[T], 0, len(items))
for i, v := range items {
if filter == nil || filter(i, v) {
filteredItems = append(filteredItems, IndexedItem[T]{
Index: i,
Item: v,
})
}
}
return Combinations(filteredItems, size)
}