Cartesian product of two or more lists: Difference between revisions

Content added Content deleted
(→‎{{header|Groovy}}: Initial solution)
(→‎{{header|Groovy}}: Changed to a "more natural" multiply operator overload)
Line 844: Line 844:


=={{header|Groovy}}==
=={{header|Groovy}}==
'''Solution:'''
'''Solution:'''<br>
The following ''CartesianCategory'' class allows for modification of regular ''Iterable'' interface behavior, overloading ''Iterable'''s ''multiply'' (*) operator to perform a Cartesian Product when the second operand is also an ''Iterable''.
<lang groovy>def cartProd(Iterable ... lists) {
<lang groovy>class CartesianCategory {
assert lists
static Iterable multiply(Iterable a, Iterable b) {
def order = lists.size()
assert order > 1
assert [a,b].every { it != null }
def dims = lists*.size()
def (m,n) = [a.size(),b.size()]
(0..<(m*n)).inject([]) { prod, i -> prod << [a[i.intdiv(n)], b[i%n]].flatten() }
if (order == 2) {
def (n0,n1) = dims
(0..<(n0*n1)).inject([]) { prod, i -> prod << [lists[0][i.intdiv(n1)],lists[1][i%n1]] }
} else {
def (l1,l2) = lists[0..1]
Iterable[] newLists = [cartProd(l1,l2)] + lists[2..<order]
cartProd(newLists).collect { it.flatten() }
}
}
}</lang>
}</lang>
'''Test:'''
'''Test:'''<br>
The ''mixin'' method call is necessary to make the multiply (*) operator work.
<lang groovy>println "[1, 2] × [3, 4] = ${cartProd([1, 2], [3, 4])}"
<lang groovy>Iterable.metaClass.mixin CartesianCategory
println "[3, 4] × [1, 2] = ${cartProd([3, 4], [1, 2])}"

println "[1, 2] × [] = ${cartProd([1, 2], [])}"
println "[] × [1, 2] = ${cartProd([], [1, 2])}"
println "[1, 2] × [3, 4] = ${[1, 2] * [3, 4]}"
println "[1776, 1789] × [7, 12] × [4, 14, 23] × [0, 1] = ${cartProd([1776, 1789], [7, 12], [4, 14, 23], [0, 1])}"
println "[3, 4] × [1, 2] = ${[3, 4] * [1, 2]}"
println "[1, 2, 3] × [30] × [500, 100] = ${cartProd([1, 2, 3], [30], [500, 100])}"
println "[1, 2] × [] = ${[1, 2] * []}"
println "[1, 2, 3] × [] × [500, 100] = ${cartProd([1, 2, 3], [], [500, 100])}"
println "[] × [1, 2] = ${[] * [1, 2]}"
println "[1776, 1789] × [7, 12] × [4, 14, 23] × [0, 1] = ${[1776, 1789] * [7, 12] * [4, 14, 23] * [0, 1]}"
println "[1, 2, 3] × [30] × [500, 100] = ${[1, 2, 3] * [30] * [500, 100]}"
println "[1, 2, 3] × [] × [500, 100] = ${[1, 2, 3] * [] * [500, 100]}"


println "[John,Paul,George,Ringo] × [Emerson,Lake,Palmer] × [Simon,Garfunkle] = ["
println "[John,Paul,George,Ringo] × [Emerson,Lake,Palmer] × [Simon,Garfunkle] = ["
cartProd(["John","Paul","George","Ringo"], ["Emerson","Lake","Palmer"], ["Simon","Garfunkle"]).each { println "\t${it}," }
( ["John","Paul","George","Ringo"] * ["Emerson","Lake","Palmer"] * ["Simon","Garfunkle"] ).each { println "\t${it}," }
println "]"</lang>
println "]"</lang>
'''Output:'''
'''Output:'''