ryanhaining / cppitertools

Implementation of python itertools and builtin iteration functions for C++17
https://twitter.com/cppitertools
BSD 2-Clause "Simplified" License
1.37k stars 115 forks source link

`product` with repeats as an argument #78

Open simonzack opened 4 years ago

simonzack commented 4 years ago

Hi, I came here from doing Project Euler in C++.

I was googling for a library for doing product() and found this one, but it only allows a template argument.

My use-case is to have seq be the digits {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, and repeats be the number of them. This is required for some problems.

Having repeats would be great!

ryanhaining commented 4 years ago

Sorry for the delayed response. You're not the first person to ask for something similar (see #41). The issue is that product is able to handle different types, and so must compute a lot at compile time. The flexibility you'd need would require a totally different product implementation that did work at runtime unless you know the repeat value that you need at compile time. Is that the case? So that something like product_repeat<3>(digits) could work for you?

simonzack commented 4 years ago

Oh I basically need the same type but repeated different times, but the repeat value is not known at compile time.

A couple days ago I just did this manually by representing each possibility as a number, and extracting the digits. My set of digits were {1, 3, 7, 9}, and 1 encoded as 0, 3 encoded as 1, 7 encoded as 2, 9 encoded as 3, 11 encoded as 4 and so on. But some product() like Python's itertools I think will be more flexible.

The number of repeats is in a loop, so product_repeat<3>(digits) wouldn't work too well. It would if the loop was templated in some way, but that's not very nice.

Is it hard to make this a real parameter or would it slow things down lots? I'm guessing it'll be slower than the encoding scheme I had above, but hopefully not too much.

ryanhaining commented 4 years ago

It's probably easier than implementing the existing version of product, the problem is that it's not a tweak, it's a from scratch implementation.

If you knew the upper bound and lower bounds at compile time you could maybe use c++20 consteval to do it, but it's not gonna be very elegant

On Tue, Jul 28, 2020, 1:49 AM simonzack notifications@github.com wrote:

Oh I basically need the same type but repeated different times, but the repeat value is not known at compile time.

A couple days ago I just did this manually by representing the product of digits as numbers, and extracting the digits. But some product() like Python's itertools I think will be more flexible.

The number of repeats is in a loop, so product_repeat<3>(digits) wouldn't work too well. It would if the loop was templated in some way, but that's not very pretty I'm guessing.

Is it hard to make this a real parameter or would it slow things down lots?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ryanhaining/cppitertools/issues/78#issuecomment-664879654, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIWWWJJJI4GTMNU63ZXRATR52GKJANCNFSM4O7WETQQ .

simonzack commented 4 years ago

Well I know the lower bound but not the upper bound.

And yes consteval & template stuff is not very elegant and seems like it's hard-coded. I barely know how to code template meta-programming stuff anyway.

I think the ideal form is something like Python and making it an argument. I think that's perfect if there's not a massive decrease in performance compared to just using a loop, encoding the indexes as numbers, and decoding it. That works but is rather tedious to code.

ryanhaining commented 4 years ago

I'm not disagreeing about the ideal, it's just a totally different implementation than the existing product

On Wed, Jul 29, 2020, 2:17 AM simonzack notifications@github.com wrote:

Well I know the lower bound but not the upper bound.

And yes consteval & template stuff is not very elegant and seems like it's hard-coded. I barely know how to code template meta-programming stuff anyway.

I think the ideal form is something like Python and making it an argument. I think that's perfect if there's not a massive decrease in performance compared to just encoding the indexes in loops and decoding it that way. That works but is rather tedious to code.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ryanhaining/cppitertools/issues/78#issuecomment-665544953, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIWWWMUT5QFVC7QCBSGE5LR57SKZANCNFSM4O7WETQQ .