add PermutationsAllSizes
This commit is contained in:
parent
61655a2799
commit
65bd8c99d0
2
go.sum
Normal file
2
go.sum
Normal file
@ -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
|
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 uses Heap's Algorithm to generate a list of all possible
|
||||||
permutations of the provided list. Most slices will automatically coerce
|
permutations of the provided list.
|
||||||
their type into a GenSlice[T] with no casting required
|
|
||||||
*/
|
*/
|
||||||
func Permutations[T any](arr GenSlice[T]) []GenSlice[T] {
|
func Permutations[T comparable](arr []T) [][]T {
|
||||||
var helper func(GenSlice[T], int)
|
var heapsAlgo func([]T, int)
|
||||||
var res []GenSlice[T]
|
var res [][]T
|
||||||
|
|
||||||
helper = func(arr GenSlice[T], n int) {
|
heapsAlgo = func(arr []T, n int) {
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
var tmp GenSlice[T]
|
var tmp []T
|
||||||
for _, i := range arr {
|
for _, i := range arr {
|
||||||
tmp = append(tmp, i)
|
tmp = append(tmp, i)
|
||||||
}
|
}
|
||||||
res = append(res, tmp)
|
res = append(res, tmp)
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
helper(arr, n-1)
|
heapsAlgo(arr, n-1)
|
||||||
if n%2 == 1 {
|
if n%2 == 1 {
|
||||||
tmp := arr[i]
|
tmp := arr[i]
|
||||||
arr[i] = arr[n-1]
|
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
|
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
|
package permutation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func TestPermutations(t *testing.T) {
|
||||||
a := []int{1, 2, 3, 4}
|
testCases := []struct {
|
||||||
p := Permutations(a)
|
name string
|
||||||
fmt.Println(p)
|
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…
x
Reference in New Issue
Block a user