commit - 61655a2799a381feeccfd31bdcb622eb1fb24b5e
commit + 65bd8c99d072f7f61b5304f098001ecc71f82e71
blob - 6fb9ea8233f44c549ae5a951b6d5752010f560ce
blob + be6f6d2e6b56ad69876d505078027d0d98c97c80
--- permutation.go
+++ permutation.go
*/
package permutation
-// GenSlice is a generic slice of data
-type GenSlice[T any] []T
-
/*
Permutations uses Heap's Algorithm to generate a list of all possible
-permutations of the provided list. Most slices will automatically coerce
-their type into a GenSlice[T] with no casting required
+permutations of the provided list.
*/
-func Permutations[T any](arr GenSlice[T]) []GenSlice[T] {
- var helper func(GenSlice[T], int)
- var res []GenSlice[T]
+func Permutations[T comparable](arr []T) [][]T {
+ var heapsAlgo func([]T, int)
+ var res [][]T
- helper = func(arr GenSlice[T], n int) {
+ heapsAlgo = func(arr []T, n int) {
if n == 1 {
- var tmp GenSlice[T]
+ var tmp []T
for _, i := range arr {
tmp = append(tmp, i)
}
res = append(res, tmp)
} else {
for i := 0; i < n; i++ {
- helper(arr, n-1)
+ heapsAlgo(arr, n-1)
if n%2 == 1 {
tmp := arr[i]
arr[i] = arr[n-1]
}
}
}
- helper(arr, len(arr))
+ heapsAlgo(arr, len(arr))
return res
}
+
+/*
+PermutationsAllSizes returns all permutations of every possible combination in a slice.
+This includes single item sets.
+*/
+func PermutationsAllSizes[T comparable](arr []T) (result [][]T) {
+ sets := generateSets(arr)
+ for _, set := range sets {
+ perms := Permutations(set)
+ for _, perm := range perms {
+ result = append(result, perm)
+ }
+ }
+ return result
+}
+
+func generateSets[T comparable](arr []T) (result [][]T) {
+ l := uint(len(arr))
+ for b := 1; b < (1 << l); b++ {
+ var s []T
+ for i := uint(0); i < l; i++ {
+ if (b>>i)&1 == 1 {
+ s = append(s, arr[i])
+ }
+ }
+ result = append(result, s)
+ }
+ return result
+}
blob - /dev/null
blob + 9aac26a1baca7f8e11b197fad7164a4216842f34 (mode 644)
--- /dev/null
+++ go.sum
+golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE=
+golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
blob - 7bb94ec4947a0869eaae87b5718d42b8745b1bef
blob + 98e18775f57aef39edeecc191c1919f355556b79
--- permutation_test.go
+++ permutation_test.go
package permutation
import (
- "fmt"
"testing"
)
-func Test(t *testing.T) {
- a := []int{1, 2, 3, 4}
- p := Permutations(a)
- fmt.Println(p)
+func TestPermutations(t *testing.T) {
+ testCases := []struct {
+ name string
+ seed []int
+ permsExpected int
+ }{
+ {
+ "basic",
+ []int{1, 2, 3},
+ 6,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ perms := Permutations(testCase.seed)
+ if len(perms) != testCase.permsExpected {
+ t.Errorf("len(perms) == %d, expected %d", len(perms), testCase.permsExpected)
+ }
+ })
+ }
}
+
+func TestPermutationsAllSizes(t *testing.T) {
+ testCases := []struct {
+ name string
+ seed []int
+ permsExpected int
+ }{
+ {
+ "3 ints",
+ []int{1, 2, 3},
+ 15,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ perms := PermutationsAllSizes(testCase.seed)
+ if len(perms) != testCase.permsExpected {
+ t.Errorf("len(perms) == %d, expected %d", len(perms), testCase.permsExpected)
+ }
+ })
+ }
+}