pub const fn exhaustive_vecs_from_length_iterator<T: Clone, I: Iterator<Item = u64>, J: Clone + Iterator<Item = T>>(
    lengths: I,
    xs: J
) -> ExhaustiveVecs<T, I, J>
Expand description

Generates all Vecs with elements from a specified iterator and with lengths from another iterator.

The length-generating iterator is xs, and the element-generating iterator is ys.

If the lengths iterator has repetitions, then the generated Vecs will be repeated too.

There’s one quirk if ys is empty: then the iterator will stop at some point after it encounters a nonzero $\ell$, even if there are zeros later on. This prevents the iterator hanging when given an empty ys and lengths $0, 1, 2, \ldots$.

  • If ys is empty, the output length is finite.
  • If ys is infinite, the output length is infinite.
  • If ys is nonempty and finite, and xs is infinite, the output is infinite.
  • If ys is nonempty and finite, and xs is finite, the output length is $$ \sum_{k=0}^{m-1} n^{\ell_k}, $$ where $n$ is ys.count() and $m$ is xs.count().

Examples

use itertools::Itertools;
use malachite_base::bools::exhaustive::exhaustive_bools;
use malachite_base::nevers::nevers;
use malachite_base::vecs::exhaustive::exhaustive_vecs_from_length_iterator;

let xss = exhaustive_vecs_from_length_iterator([2, 1, 2].iter().cloned(), exhaustive_bools())
    .collect_vec();
assert_eq!(
    xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
    &[
        &[false, false][..],
        &[false],
        &[false, true],
        &[false, false],
        &[true, false],
        &[true],
        &[true, true],
        &[false, true],
        &[true, false],
        &[true, true]
    ]
);

let xss =
    exhaustive_vecs_from_length_iterator([0, 0, 1, 0].iter().cloned(), nevers()).collect_vec();
// Stops at some point after first empty ys
assert_eq!(
    xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
    &[&[], &[]]
);