JuliaLang/julia — pull request #425 by robert-chiniquy (2012-02-21 01:08:19+00:00)
Title: add combinations(), integer_partitions(), and partitions() to combinatorics.j

These are as described in TAoCP 7.2.1.3, 7.2.1.4, and 7.2.1.5.

All three use coroutines. Each produce() call, combinations() and integer_partitions() return Array, partitions() returns a set of sets. partitions() could have been written to return a generator which would return each set from an individual partitioning in turn, I wasn't sure what the preferred behavior would be so I went simple if clunky.

Here's my test script and the output:

macro task(ex); :(Task(()->$ex)); end

function test_combinations(a, t)
println(length(a), ',', t)
println("nCr: ", binomial(length(a), t))
for comb in @task combinations(a, t)
println(comb)
end
end

test_combinations(['a','b','c','d','e','f'], 4)

test_combinations(['a','b','c','d','e'], 4)
test_combinations(['a','b','c','d'], 3)
test_combinations(['a','b','c','d'], 2)
test_combinations(['a','b','c'], 2)
test_combinations(['a','b','c'], 1)
test_combinations(['a','b'], 1)

function test_integer_partitions(n, m)
println("n, m: ", n, ',', m)
for int_part in @task integer_partitions(n, m)
println(int_part)
end
end

for i = 4:5
for j = 2:4
test_integer_partitions(i, j)
end
end

function test_partitions(s)
println("s: ", s)
for part in @task partitions(s)
println(part)
end
end

test_partitions(['a', 'b', 'c', 'd'])

OUTPUT:

6,4
nCr: 15
{'a', 'b', 'c', 'd'}
{'a', 'b', 'c', 'e'}
{'a', 'b', 'd', 'e'}
{'a', 'c', 'd', 'e'}
{'b', 'c', 'd', 'e'}
{'a', 'b', 'c', 'f'}
{'a', 'b', 'd', 'f'}
{'a', 'c', 'd', 'f'}
{'b', 'c', 'd', 'f'}
{'a', 'b', 'e', 'f'}
{'a', 'c', 'e', 'f'}
{'b', 'c', 'e', 'f'}
{'a', 'd', 'e', 'f'}
{'b', 'd', 'e', 'f'}
{'c', 'd', 'e', 'f'}
5,4
nCr: 5
{'a', 'b', 'c', 'd'}
{'a', 'b', 'c', 'e'}
{'a', 'b', 'd', 'e'}
{'a', 'c', 'd', 'e'}
{'b', 'c', 'd', 'e'}
4,3
nCr: 4
{'a', 'b', 'c'}
{'a', 'b', 'd'}
{'a', 'c', 'd'}
{'b', 'c', 'd'}
4,2
nCr: 6
{'a', 'b'}
{'a', 'c'}
{'b', 'c'}
{'a', 'd'}
{'b', 'd'}
{'c', 'd'}
3,2
nCr: 3
{'a', 'b'}
{'a', 'c'}
{'b', 'c'}
3,1
nCr: 3
{'a'}
{'b'}
{'c'}
2,1
nCr: 2
{'a'}
{'b'}
n, m: 4,2
[3.0, 1.0]
[2.0, 2.0]
n, m: 4,3
[2.0, 1.0, 1.0]
n, m: 4,4
[1.0, 1.0, 1.0, 1.0]
n, m: 5,2
[4.0, 1.0]
[3.0, 2.0]
n, m: 5,3
[3.0, 1.0, 1.0]
[2.0, 2.0, 1.0]
n, m: 5,4
[2.0, 1.0, 1.0, 1.0]
s: ['a', 'b', 'c', 'd']
Set{Any}(Set{Any}('a','c','b','d'))
Set{Any}(Set{Any}('a','c','b'),Set{Any}('d'))
Set{Any}(Set{Any}('a','b','d'),Set{Any}('c'))
Set{Any}(Set{Any}('a','b'),Set{Any}('c','d'))
Set{Any}(Set{Any}('a','b'),Set{Any}('c'),Set{Any}('d'))
Set{Any}(Set{Any}('a','c','d'),Set{Any}('b'))
Set{Any}(Set{Any}('a','c'),Set{Any}('b','d'))
Set{Any}(Set{Any}('a','c'),Set{Any}('b'),Set{Any}('d'))
Set{Any}(Set{Any}('a','d'),Set{Any}('c','b'))
Set{Any}(Set{Any}('a'),Set{Any}('c','b','d'))
Set{Any}(Set{Any}('a'),Set{Any}('c','b'),Set{Any}('d'))
Set{Any}(Set{Any}('a','d'),Set{Any}('b'),Set{Any}('c'))
Set{Any}(Set{Any}('a'),Set{Any}('b','d'),Set{Any}('c'))
Set{Any}(Set{Any}('a'),Set{Any}('b'),Set{Any}('c','d'))
Set{Any}(Set{Any}('b'),Set{Any}('d'),Set{Any}('a'),Set{Any}('c'))