Skip to content

Instantly share code, notes, and snippets.

@NickBeeuwsaert
Created May 12, 2019 02:14
Show Gist options
  • Save NickBeeuwsaert/fb01328390b923069bda5322f8d68b5f to your computer and use it in GitHub Desktop.
Save NickBeeuwsaert/fb01328390b923069bda5322f8d68b5f to your computer and use it in GitHub Desktop.
Cartesian Product
function* cartesianProduct(...iterables) {
const pools = iterables.map(function(iterable) {
const pool = Array.from(iterable);
return {pool, length: pool.length, counter: 0};
});
let iterations = pools.reduce(
(total, {length}) => total * length,
1
);
while(iterations--) {
yield pools.map(({counter, pool}) => pool[counter]);
for(const pool of pools) {
pool.counter++;
if(pool.counter < pool.length) {
break;
}
pool.counter = 0;
}
}
}
import functools
import itertools
import operator
import pytest
def product(*iterables):
pools = [tuple(iterable) for iterable in iterables]
iterations = functools.reduce(operator.mul, map(len, pools))
for i in range(iterations):
result = []
for pool in pools:
result.append(pool[i % len(pool)])
i //= len(pool)
yield tuple(result)
class CartesianProduct:
def __init__(self, *iterables):
self.pools = [tuple(iterable) for iterable in iterables]
def __len__(self):
return functools.reduce(
operator.mul,
map(len, self.pools)
)
def __getitem__(self, idx):
result = []
for pool in self.pools:
result.append(pool[idx % len(pool)])
idx = idx // len(pool)
return tuple(result)
def __iter__(self):
for i in range(len(self)):
yield self[i]
@pytest.mark.parametrize('a', [
([1, 2], [3, 4]),
([1], [2]),
([1, 2, 3], [1, 2]),
([1, 2], [3, 4], [5, 6]),
([1], [2, 3], [4, 5, 6], [7, 8, 9, 10]),
([1, 2, 3, 4], [5, 6, 7], [8, 9], [10]),
])
def test_product(a):
assert sorted(itertools.product(*a)) == sorted(product(*a))
@pytest.mark.parametrize('a', [
([1, 2], [3, 4]),
([1], [2]),
([1, 2, 3], [1, 2]),
([1, 2], [3, 4], [5, 6]),
([1], [2, 3], [4, 5, 6], [7, 8, 9, 10]),
([1, 2, 3, 4], [5, 6, 7], [8, 9], [10]),
])
def test_cartesianproduct(a):
cart_prod = CartesianProduct(*a)
assert sorted(itertools.product(*a)) == sorted(cart_prod)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment