from typing import TypeVar, Collection from tudelft.utilities.immutablelist.ImmutableList import ImmutableList from tudelft.utilities.immutablelist.Tuple import Tuple from tudelft.utilities.immutablelist.AbstractImmutableList import AbstractImmutableList T1 = TypeVar('T1') T2 = TypeVar('T2') class Tuples(AbstractImmutableList[Tuple[T1,T2]]): ''' Generate list of Tuple[T1, T2] with all combinations of 1 element from list1 and one from list2. Sometimes called "cartesian product". You can use this recursively to generate bigger products; but you can also use {@link Outer}. @param type of the first element of the tuple @param type of the second element of the tuple @param type of the elements ''' def __init__(self, list1:ImmutableList[T1], list2:ImmutableList[T2] ): ''' contains all possible tuples with first element from list1 and second from list2 @param list1 first element list @param list2 second element list ''' self._list1 = list1 self._list2 = list2 self._size = list1.size()* list2.size() def get(self, index:int) -> Tuple[T1, T2] : indices = divmod(index,self._list1.size()) return Tuple(self._list1.get(indices[1]), self._list2.get(indices[0])) def size(self) ->int: return self._size def __hash__(self): return hash((self._list1, self._list2)) def __eq__(self, other): return isinstance(other, self.__class__) \ and self._list1==other._list1\ and self._list2==other._list2