private class CombinationIterator[E]
super Iterator[SequenceRead[E]]
var product: CombinationCollection[E]
var iterators = new Array[Iterator[E]]
var indices = new Array[Int]
var are_sorted: Bool is noinit
var are_unique: Bool is noinit
init
do
are_sorted = product.are_sorted
are_unique = product.are_unique
for rank in [0..product.repeat[ do
reset_iterator(rank)
end
end
redef var is_ok = true
redef fun item
do
var len = product.repeat
var res = new Array[E].with_capacity(len)
for i in [0..len[ do
var it = iterators[i]
res.add(it.item)
end
return res
end
redef fun next
do
var rank = product.repeat - 1
loop
var it = iterators[rank]
if are_unique and not are_sorted then
var idx = indices[rank] + 1
it.next
var adv = next_free(rank, idx)
for i in [idx..adv[ do it.next
indices[rank] = adv
else
it.next
indices[rank] += 1
end
if it.is_ok then break
if rank == 0 then
is_ok = false
return
end
rank -= 1
end
for r in [rank+1..product.repeat[ do
reset_iterator(r)
end
end
fun next_free(rank: Int, start: Int): Int
do
loop
for i in [0..rank[ do
if indices[i] == start then
start += 1
continue label
end
end
break label
end label
return start
end
fun reset_iterator(rank: Int): Iterator[E]
do
var it = product.collection.iterator
iterators[rank] = it
var skip = 0
if (not are_sorted and not are_unique) or rank == 0 then
# DO NOTHING
else if are_sorted and are_unique then
skip = indices[rank-1] + 1
else if are_sorted then
skip = indices[rank-1]
else
skip = next_free(rank, 0)
end
for i in [0..skip[ do it.next
indices[rank] = skip
if not it.is_ok then is_ok = false
return it
end
fun need_skip: Bool
do
if not are_sorted and not are_unique then
return false
else if are_sorted and are_unique then
var max = -1
for i in indices do
if i <= max then return true
max = i
end
return false
else if are_sorted then
var max = -1
for i in indices do
if i < max then return true
max = i
end
return false
else
# are_unique
for i in indices do
if indices.count(i) > 1 then return true
end
return false
end
end
end
lib/combinations/combinations.nit:313,1--439,3