## digitalmars.D.learn - Set operation like cartesian product

• Andrea Fontana (11/11) Feb 28 2013 I see cartesianProduct in std.algorithm. I read:
• Andrea Fontana (9/20) Feb 28 2013 PS: In my case I can't use filter!(...): I'm trying to compare an
• H. S. Teoh (27/40) Feb 28 2013 [...]
• Andrea Fontana (4/47) Feb 28 2013 triangulaProduct2 for [0,1,2,3] and [0,1,2,3] doesn't give (0,0)
• H. S. Teoh (18/42) Feb 28 2013 Ahhh, slight mistake there, it should be:
• H. S. Teoh (8/42) Feb 28 2013 [...]
```I see cartesianProduct in std.algorithm. I read:

auto N = sequence!"n"(0); // the range of natural numbers
auto N2 = cartesianProduct(N, N); // the range of all pairs of
natural numbers

So it gives (0,0) (0,1) (1,0) ... and so on.

Is there a way to generate only tuple:

a > a (0,1) (0,2) ... (1,2) (1,3) .. (2,3) (2,4)

or

a >= a (0,0) (0,1) (0,2) ... (1,1) (1,2) (1,3) .. (2,2)
(2,3) (2,4)

Or the only way is use filter!(...) after cartesianProduct?
```
Feb 28 2013
```On Thursday, 28 February 2013 at 15:32:00 UTC, Andrea Fontana
wrote:
I see cartesianProduct in std.algorithm. I read:

auto N = sequence!"n"(0); // the range of natural numbers
auto N2 = cartesianProduct(N, N); // the range of all pairs of
natural numbers

So it gives (0,0) (0,1) (1,0) ... and so on.

Is there a way to generate only tuple:

a > a (0,1) (0,2) ... (1,2) (1,3) .. (2,3) (2,4)

or

a >= a (0,0) (0,1) (0,2) ... (1,1) (1,2) (1,3) .. (2,2)
(2,3) (2,4)

Or the only way is use filter!(...) after cartesianProduct?

PS: In my case I can't use filter!(...): I'm trying to compare an
array of struct with itself to find similar ones, so I can't
filter Tuple(struct, struct) in any way...

I have to write:

for (i; 0..arr.length) for(j; i+1..arr.length) // check arr[i]
and arr[j] for similarities

Any ideas?
```
Feb 28 2013
```Andrea Fontana:

Any ideas?

I suggested pairwise():
http://d.puremagic.com/issues/show_bug.cgi?id=6788

Bye,
bearophile
```
Feb 28 2013
```On Thu, Feb 28, 2013 at 04:31:59PM +0100, Andrea Fontana wrote:
I see cartesianProduct in std.algorithm. I read:

auto N = sequence!"n"(0); // the range of natural numbers
auto N2 = cartesianProduct(N, N); // the range of all pairs of
natural numbers

So it gives (0,0) (0,1) (1,0) ... and so on.

Is there a way to generate only tuple:

a > a (0,1) (0,2) ... (1,2) (1,3) .. (2,3) (2,4)

[...]

auto triangularProduct(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a), repeat(a)))(
zip(sequence!"n"(0), repeat(r1.save), r2)
)
.joiner();
}

Both ranges can be infinite, only the first one needs to be a forward
range.

a >= a (0,0) (0,1) (0,2) ... (1,1) (1,2) (1,3) .. (2,2) (2,3)
(2,4)

[...]

auto triangularProduct2(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a), repeat(a)))(
zip(sequence!"n"(1), repeat(r1.save), r2)
)
.joiner();
}

As above, both ranges can be infinite, only the first one needs to be a
forward range.

Hope this helps. ;-)

T

--
Gone Chopin. Bach in a minuet.
```
Feb 28 2013
```On Thursday, 28 February 2013 at 18:23:04 UTC, H. S. Teoh wrote:
On Thu, Feb 28, 2013 at 04:31:59PM +0100, Andrea Fontana wrote:
I see cartesianProduct in std.algorithm. I read:

auto N = sequence!"n"(0); // the range of natural numbers
auto N2 = cartesianProduct(N, N); // the range of all pairs of
natural numbers

So it gives (0,0) (0,1) (1,0) ... and so on.

Is there a way to generate only tuple:

a > a (0,1) (0,2) ... (1,2) (1,3) .. (2,3) (2,4)

[...]

auto triangularProduct(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a),
repeat(a)))(
zip(sequence!"n"(0), repeat(r1.save), r2)
)
.joiner();
}

Both ranges can be infinite, only the first one needs to be a
forward
range.

a >= a (0,0) (0,1) (0,2) ... (1,1) (1,2) (1,3) .. (2,2)
(2,3)
(2,4)

[...]

auto triangularProduct2(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a),
repeat(a)))(
zip(sequence!"n"(1), repeat(r1.save), r2)
)
.joiner();
}

As above, both ranges can be infinite, only the first one needs
to be a
forward range.

Hope this helps. ;-)

T

triangulaProduct2 for [0,1,2,3] and [0,1,2,3] doesn't give (0,0)
(1,1) (2,2) (3,3)

:)
```
Feb 28 2013
```On Thu, Feb 28, 2013 at 09:20:52PM +0100, Andrea Fontana wrote:
On Thursday, 28 February 2013 at 18:23:04 UTC, H. S. Teoh wrote:

[...]
auto triangularProduct2(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a),
repeat(a)))(
zip(sequence!"n"(1), repeat(r1.save), r2)
)
.joiner();
}

As above, both ranges can be infinite, only the first one needs to
be a
forward range.

Hope this helps. ;-)

T

triangulaProduct2 for [0,1,2,3] and [0,1,2,3] doesn't give (0,0)
(1,1) (2,2) (3,3)

:)

Ahhh, slight mistake there, it should be:

auto triangularProduct2(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a+1), repeat(a)))(
zip(sequence!"n"(1), repeat(r1.save), r2)
)
.joiner();
}

There, better now? ;-)

Also, if you only need products of finite ranges, it's possible to
rewrite it so that it produces items in a nicer order. The strange order
output by my examples are to cater for the infinite case.

T

--
Life would be easier if I had the source code. -- YHL
```
Feb 28 2013    "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
```On Thu, Feb 28, 2013 at 03:01:48PM -0800, H. S. Teoh wrote:
On Thu, Feb 28, 2013 at 09:20:52PM +0100, Andrea Fontana wrote:
On Thursday, 28 February 2013 at 18:23:04 UTC, H. S. Teoh wrote:

[...]
auto triangularProduct2(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a),
repeat(a)))(
zip(sequence!"n"(1), repeat(r1.save), r2)
)
.joiner();
}

As above, both ranges can be infinite, only the first one needs to
be a
forward range.

Hope this helps. ;-)

T

triangulaProduct2 for [0,1,2,3] and [0,1,2,3] doesn't give (0,0)
(1,1) (2,2) (3,3)

:)

Ahhh, slight mistake there, it should be:

auto triangularProduct2(R1,R2)(R1 r1, R2 r2)
if (isForwardRange!R1)
{
return map!(function(a) => zip(take(a.save, a+1), repeat(a)))(
zip(sequence!"n"(1), repeat(r1.save), r2)

[...]

Argh. Another mistake. The above line should read:

zip(sequence!"n"(0), repeat(r1.save), r2)

:-/

T

--
Once bitten, twice cry...
```
Feb 28 2013