From 83b9ae411d3db73775fece152bc2d2f7a43261c0 Mon Sep 17 00:00:00 2001 From: Laurent Demailly Date: Tue, 4 Jun 2024 10:09:27 -0700 Subject: [PATCH] Adding Tuplets functions to generate all n-tuplets (pairs, triplets etc) --- sets.go | 25 +++++++++++++++++++++++++ sets_test.go | 12 +++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/sets.go b/sets.go index e06d72b..9e4273b 100644 --- a/sets.go +++ b/sets.go @@ -226,3 +226,28 @@ func Sort[Q constraints.Ordered](s Set[Q]) []Q { slices.Sort(keys) return keys } + +// Tuplets generates all the combinations of N of elements of the set. +// for n = 2, it would return all pairs of elements. +// for n = 3, all triplets, etc. +func Tuplets[Q constraints.Ordered](s Set[Q], n int) [][]Q { + if n == 0 { + return [][]Q{{}} + } + if n == 1 { + res := make([][]Q, s.Len()) + for i, e := range Sort(s) { + v := []Q{e} + res[i] = v + } + return res + } + res := make([][]Q, 0) + for _, e := range Sort(s) { + t := s.Clone() + for _, sub := range Tuplets(t.Minus(New(e)), n-1) { + res = append(res, append([]Q{e}, sub...)) + } + } + return res +} diff --git a/sets_test.go b/sets_test.go index f83310e..4e0e4c6 100644 --- a/sets_test.go +++ b/sets_test.go @@ -157,12 +157,22 @@ func TestNonOrderedJSON(t *testing.T) { // though I guess given it could be in any order it could be accidentally sorted too assert.NotEqual(t, `[{"X":1},{"X":2},{"X":3},{"X":4}]`, string(b)) u := sets.New[foo]() - json.Unmarshal(b, &u) + err = json.Unmarshal(b, &u) assert.NoError(t, err) assert.Equal(t, 4, u.Len()) assert.True(t, s.Equals(u)) } +func TestGenerate(t *testing.T) { + setA := sets.New("a", "b", "c") + res := sets.Tuplets(setA, 1) + assert.Equal(t, res, [][]string{{"a"}, {"b"}, {"c"}}, "should match single/identical") + res = sets.Tuplets(setA, 2) + assert.Equal(t, res, [][]string{{"a", "b"}, {"a", "c"}, {"b", "a"}, {"b", "c"}, {"c", "a"}, {"c", "b"}}, "should match pairs") + res = sets.Tuplets(setA, 3) + assert.Equal(t, res, [][]string{{"a", "b", "c"}, {"a", "c", "b"}, {"b", "a", "c"}, {"b", "c", "a"}, {"c", "a", "b"}, {"c", "b", "a"}}, "should match triplets") +} + func TestBadJson(t *testing.T) { jsonStr := `[ "a,b",