add PermutationsAllSizes
This commit is contained in:
parent
61655a2799
commit
65bd8c99d0
|
@ -0,0 +1,2 @@
|
|||
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=
|
|
@ -4,28 +4,24 @@ lists. It uses Go 1.18's new generics feature to provide a generic interface
|
|||
*/
|
||||
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]
|
||||
|
@ -38,6 +34,35 @@ func Permutations[T any](arr GenSlice[T]) []GenSlice[T] {
|
|||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,12 +1,51 @@
|
|||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue