added Cartesian product

This commit is contained in:
Simon Hafner
2014-01-30 02:07:21 -06:00
parent 47e2999fec
commit ac0f15379c
2 changed files with 41 additions and 0 deletions

View File

@@ -131,3 +131,35 @@ proc sort*[T](a: var openArray[T],
dec(m, s*2)
s = s*2
proc product[T](x: openarray[seq[T]]): seq[seq[T]] =
## produces the Cartesian product of the array. Warning: complexity
## may explode.
result = @[]
if x.len == 0:
return
if x.len == 1:
result = @x
return
var
indexes = newSeq[int](x.len)
initial = newSeq[int](x.len)
index = 0
# replace with newSeq as soon as #853 is fixed
var next: seq[T] = @[]
next.setLen(x.len)
for i in 0..(x.len-1):
initial[i] = len(x[i])-1
indexes = initial
while true:
while indexes[index] == -1:
indexes[index] = initial[index]
index +=1
if index == x.len: return
indexes[index] -=1
for ni, i in indexes:
next[ni] = x[ni][i]
var res: seq[T]
shallowCopy(res, next)
result.add(res)
index = 0
indexes[index] -=1

View File

@@ -0,0 +1,9 @@
import unittest
suite "product":
test "a simple case of one element":
check product(@[@[1,2]]) == @[@[1,2]]
test "two elements":
check product(@[@[1,2], @[3,4]]) == @[@[2,4],@[1,4],@[2,3],@[1,3]]
test "three elements":
check product(@[@[1,2], @[3,4], @[5,6]]) == @[@[2,4,6],@[1,4,6],@[2,3,6],@[1,3,6], @[2,4,5],@[1,4,5],@[2,3,5],@[1,3,5]]