How to get the result of combinations_with_replacement from itertools into an array

Hello everyone,

I am trying to create a function combo which accepts two variables n and b and returns an array res containing all possible combinations. I want to create a dll and use it in a C program later. For example for n=4 and r=3 the following array should be returned:

[[1, 2, 3],
[1, 2, 4],
[1, 3, 4],
[2, 3, 4]];

The function I have so far looks like this:

fn combo(n: usize, r: usize, res: &mut [usize]) {
    let temp = (1..n).combinations(r);

}

However; as I am new to Rust I am not able to convert temp into array and insert its values into res. Any ideas on how I could do this? Or perhaps any other approaches I could attempt?

Thanks in advance for any help or suggestions!

I'm not getting what your requirement is. The iterator created by combinations() yields several Vectors, one for each combination. How do you want to convert that into a single slice? Do you want to flatten their contents into a single big continuous stream?

Hey, thanks for the quick reply. Yes, I want to get all of the results and insert it into a 2 x N array. Is that even possible? My problem is also that I don't know how to access the vectors which combinations() yields e.g. by using iter or collect, that is why I can't even access the yielded vectors and print them to the screen ... :sweat_smile:

But not all combinations have 2 elements, it sounds like you want to populate an array of dimensions r and k (where k is whatever the length of the iterator is)?

Sorry, I meant 3xN for the example. Yes, I would like to populate a result array of dimensions r and k. k in this case would be mathematically speaking:

k = nCr = n! / ( r! * ( n - r )! )

where ! is the factorial function.

combinations_with_replacement() and combinations() both return iterators. You need something to drive the iterator and copy into the slice parameter. Given that you want the vectors flattened, you should call flatten() after combinations(). You can then use a for loop to iterate over it and copy the data across. You'll need some way of indexing res to do the copy though. One approach would be to zip the iterator with a mutable iterator over res then assign to each slot that returns:


fn combo(n: usize, r: usize, res: &mut [usize]) {
    for (x, res_slot) in (1..n).combinations(r).flatten().zip(res.iter_mut()) {
        *res_slot = x;
    }
}

(playground)

Note that this truncates if res is not large enough. Also, 1..n actually only goes up to n-1; you probably want to use 1..=n.

2 Likes

Thank you, just what I was looking for. @H2CO3 was very patient with me but my explanation was perhaps a bit convoluted. I don't really understand it yet, but I will dig in and use it as an opportunity to learn more about Rust! Thanks @jameseb7 and @H2CO3!

flatten() simply converts an iterator-over-iterables to an iterator that yields the contents of each inner iterator in sequence. zip takes two iterators and consumes them in lockstep, yielding pairs of elements from both. You can read the documentation of these and other useful methods on the Iterator trait.

1 Like