Skip to content

Commit

Permalink
Adding Tuplets functions to generate all n-tuplets (pairs, triplets e…
Browse files Browse the repository at this point in the history
…tc) (#67)

* Adding Tuplets functions to generate all n-tuplets (pairs, triplets etc)

* lint fix plus tweak the 0 case
  • Loading branch information
ldemailly authored Jun 4, 2024
1 parent 0a2332e commit 3a40da8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

lint: .golangci.yml
golangci-lint run

.golangci.yml: Makefile
curl -fsS -o .golangci.yml https://raw.githubusercontent.com/fortio/workflows/main/golangci.yml

.PHONY: lint
25 changes: 25 additions & 0 deletions sets.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
21 changes: 20 additions & 1 deletion sets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,31 @@ 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, 0)
assert.Equal(t, res, [][]string{}, "should match empty")
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",
Expand Down

0 comments on commit 3a40da8

Please sign in to comment.