func (iter *ProductIterator) Reset() {
	iter.iters = 0
	iter.indices = make([]int, iter.n, iter.n)
	iter.res = make([]interface{}, iter.n, iter.n)
}
Reset returns the iterator to its starting state.
package combinatoric
import (
	"math/big"
)
type ProductIterator struct {
	pools   [][]interface{}
	n       int
	indices []int
	max   uint64
	iters uint64
	res []interface{}
}
func (iter *ProductIterator) First() []interface{} {
	iter.Reset()
	return iter.Next()
}
func (iter *ProductIterator) Next() []interface{} {
	if !iter.HasNext() {
		return nil
	}
	if iter.res[0] == nil {
		for i := range iter.res {
			iter.res[i] = iter.pools[i][0]
		}
	} else {
		for i := iter.n - 1; i >= 0; i-- {
			pool := iter.pools[i]
			iter.indices[i] += 1
			if iter.indices[i] == len(pool) {
				iter.indices[i] = 0
				iter.res[i] = pool[0]
			} else {
				iter.res[i] = pool[iter.indices[i]]
				break
			}
		}
	}
	iter.iters += 1
	return iter.res
}
func (iter *ProductIterator) HasNext() bool {
	return iter.iters < iter.max
}