Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Real combination in Groovy

Is there method or some smart way that's easy to read to make a combination of elements in Groovy? I'm aware of Iterable#combinations or GroovyCollections#combinations but it makes Partial permutation with repetition as I understand it so far. See example.

// Groovy combinations result
def e = ['a', 'b', 'c']
def result = [e, e].combinations()
assert [['a', 'a'], ['b', 'a'], ['c', 'a'], ['a', 'b'], ['b', 'b'], ['c', 'b'], ['a','c'], ['b', 'c'], ['c', 'c']] == result

// What I'm looking for
def e = ['a', 'b', 'c']
def result = ???
assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result

Feel free to post alternate solutions. I'm still looking for better readability (it's used in script for non-developers) and performance (w/o unnecessary iterations).

like image 308
michal.kreuzman Avatar asked Oct 09 '14 07:10

michal.kreuzman


2 Answers

I'm not so sure about the readability, but this should do the trick.

def e = ['a', 'b', 'c']
def result = [e, e].combinations().findAll { a, b ->
    a < b
}

assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result

Note that if a element occur twice in the list its combinations will also occur twice. Add a '.unique()' at the end if they are unwanted

like image 127
Kaffeleif Avatar answered Oct 20 '22 21:10

Kaffeleif


Here's a more generalized approach that allows you to specify the "r" value for your nCr combinations. It does this by storing permutations in Sets, with the Sets providing the uniqueness:

// returns combinations of the input list of the provided size, r
List combinationsOf(List list, int r) {
    assert (0..<list.size()).contains(r) // validate input
    def combs = [] as Set
    list.eachPermutation {
        combs << it.subList(0, r).sort { a, b -> a <=> b }
    }
    combs as List
}

// the test scenario...
def e = ['a', 'b', 'c']
def result = combinationsOf(e, 2)
assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result
like image 28
bdkosher Avatar answered Oct 20 '22 19:10

bdkosher