February 07, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #10 from bearophile_hugs@eml.cc 2013-02-07 10:17:40 PST ---
(In reply to comment #9)
> *** Issue 6788 has been marked as a duplicate of this issue. ***

It's not a dupe.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 07, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #11 from hsteoh@quickfur.ath.cx 2013-02-07 12:36:01 PST ---
https://github.com/D-Programming-Language/phobos/pull/1120

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 07, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128


Andrei Alexandrescu <andrei@erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |andrei@erdani.com
         Resolution|                            |FIXED


--- Comment #12 from Andrei Alexandrescu <andrei@erdani.com> 2013-02-07 15:01:41 PST ---
https://github.com/D-Programming-Language/phobos/pull/1120

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 08, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #13 from bearophile_hugs@eml.cc 2013-02-07 18:01:50 PST ---
The repetition number is not yet supported:

auto cartesianProduct(size_t nRepetitions=0, R)(R range) { ... }

If the name if the function is different, then it's even possible to support this API, where it returns a range of dynamic arrays:

auto cartesianPower(R)(R range, in size_t n) { ... }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 08, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128


hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |


--- Comment #14 from hsteoh@quickfur.ath.cx 2013-02-07 21:14:59 PST ---
The power must be a compile-time parameter, otherwise it won't compile. The variadic cartesianProduct only works if the number of arguments is known at compile-time.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 08, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #15 from bearophile_hugs@eml.cc 2013-02-08 04:26:20 PST ---
(In reply to comment #14)
> The power must be a compile-time parameter, otherwise it won't compile.

I think it's possible to create a range like this:

auto cartesianPower(R)(R range, in size_t n) { ... }


If you call it with:
int n = 3;
auto result = cartesianPower([0, 1], n).array();


result should be:

[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]



One use case: generate dstrings (dchar[][]) for a "Bulls and Cows" game, where they need to be composed of N distinct nonzero digits:


dchar[][] genCases(in size_t nDigits) {
  return cartesianPower("123456789"d.dup, nDigits)
         .filter!(a => a.sort().uniq().walkLength() == nDigits)()
         .array();
}


So genCases(4).writeln() should print:

["4321", "5321", "6321", "7321", "8321", "9321", "3421", "5421", "6421", "7421", "8421", "9421", "3521", "4521", "6521", "7521", "8521", "9521", "3621", "4621", "5621", "7621", "8621", "9621", "3721", "4721", "5721", "6721", "8721", "9721", "3821", "4821", "5821", "6821", "7821", "9821", "3921", "4921", "5921", ...]

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #16 from hsteoh@quickfur.ath.cx 2013-02-08 20:32:06 PST ---
Hmm, you're right. The cartesian power has the advantage that the output will be tuples of homogenous elements, so we can use arrays instead of tuples, which will allow runtime variation.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #17 from bearophile_hugs@eml.cc 2013-02-09 03:17:30 PST ---
(In reply to comment #16)
> Hmm, you're right. The cartesian power has the advantage that the output will be tuples of homogenous elements, so we can use arrays instead of tuples, which will allow runtime variation.

Right.

On the other hand if we do this, cartesianProduct() and cartesianPower() will
have different type (this means: they will be ranges that yield different class
of types, the first tuples, the second dynamic arrays). This requires people
that want to use such functions to remember this difference (a broken
symmetry). So this design decision has a little associated cost.

But in the end I prefer cartesianPower() to yield dynamic arrays because dynamic arrays are more flexible, they offer both the size_t n to be a run-time value, and dynamic arrays are more usable than tuples in D (I think tuples are not ranges). Python itertools.cartesian doesn't have such problems because Python is dynamically typed, so the items that itertools.cartesian are usable like normal sequences (unlike D tuples).

If you use a cartesianProduct() to produce the data for the "Bulls and cows" game you write something like:


auto d9 = "123456789"d.dup;
auto choices = cartesianProduct(d9, d9, d9, d9)
               .map!(t => [t.tupleof])()
               .filter!(a => a.sort().uniq().walkLength() == 4)()
               .array();


The map!(t => [t.tupleof])() is used to convert a tuple into a dynamic array,
so later on it you can perform more processing, with a filter() and an array().
D tuples don't play very well with ranges.

- - - - - - - - - - -

Maybe std.typecons.Tuple should define a handy std.typecons.Tuple.arrayof attribute (that returns [this.tupleof]) when all the items of the tuple have the same type.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=7128



--- Comment #18 from bearophile_hugs@eml.cc 2013-02-09 03:22:18 PST ---
Extra on cartesianProduct: maybe you should add a little benchmark, to be sure the way you have implemented the variadic cartesianProduct() (with the flattening of nested tuples) is efficient/fast enough:

enum N = 10; // Change me.
int[] items = iota(N).array();
immutable len = cartesianProduct(items, items, items, items,
items).walkLength();

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
1 2
Next ›   Last »