Thread overview
Replacing nested loops foreach using map/each/etc
May 25, 2015
Dennis Ritchie
May 25, 2015
Alex Parrill
May 25, 2015
Dennis Ritchie
May 25, 2015
Meta
May 25, 2015
Dennis Ritchie
May 25, 2015
Meta
May 25, 2015
Dennis Ritchie
May 25, 2015
anonymous
May 25, 2015
Dennis Ritchie
May 25, 2015
Hi,
Is it possible to write such a construction that could push immediately to a conditional statement without using nested loops? Ie organize search directly in the iterator if provided by a map / each / iota and other support functions.
Ie I want to write this code shorter :)

import std.stdio;

void main() {

    const x = 12, y = 65, z = 50, s = 1435;
	
    foreach (i; 0 .. x + 1)
        foreach (j; 0 .. x + 1)
            foreach (k; 0 .. x + 1)
                if (i * (y + 3 * z) + j * (y + 2 * z) + k * (y + z) == s) {
                    writeln(i + j + k);
                    writeln(i * 3 + j * 2 + k);
                    writeln(i * 3 + j * 2 + k);
                    writeln(i, j, k);
                }
}
-----
http://rextester.com/SJTU87854
May 25, 2015
On Monday, 25 May 2015 at 14:25:52 UTC, Dennis Ritchie wrote:
> Hi,
> Is it possible to write such a construction that could push immediately to a conditional statement without using nested loops? Ie organize search directly in the iterator if provided by a map / each / iota and other support functions.
> Ie I want to write this code shorter :)
>
> import std.stdio;
>
> void main() {
>
>     const x = 12, y = 65, z = 50, s = 1435;
> 	
>     foreach (i; 0 .. x + 1)
>         foreach (j; 0 .. x + 1)
>             foreach (k; 0 .. x + 1)
>                 if (i * (y + 3 * z) + j * (y + 2 * z) + k * (y + z) == s) {
>                     writeln(i + j + k);
>                     writeln(i * 3 + j * 2 + k);
>                     writeln(i * 3 + j * 2 + k);
>                     writeln(i, j, k);
>                 }
> }
> -----
> http://rextester.com/SJTU87854

Hint: Use `cartesianProduct` [1] with three iota ranges to replace the foreachs, and `filter` to replace the if

[1] http://dlang.org/phobos/std_algorithm_setops.html#.cartesianProduct
May 25, 2015
On Monday, 25 May 2015 at 15:06:45 UTC, Alex Parrill wrote:
> Hint: Use `cartesianProduct` [1] with three iota ranges to replace the foreachs, and `filter` to replace the if
>
> [1] http://dlang.org/phobos/std_algorithm_setops.html#.cartesianProduct

Thank you. Is it possible to replace the loop `foreach` function `each` or `chunkBy` with the auxiliary functions?

import std.stdio, std.algorithm, std.range;

void main() {

    const x = 12, y = 65, z = 50, s = 1435;

    auto a = iota(0, x + 1);

    foreach (idx; cartesianProduct(a, a, a).filter!(i => i[0] * (y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s)) {
        writeln(idx[0] + idx[1] + idx[2]);
        writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
        writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
        writeln(idx[0], idx[1], idx[2]);
    }
}
-----
http://rextester.com/HZP96719
May 25, 2015
On Monday, 25 May 2015 at 15:46:54 UTC, Dennis Ritchie wrote:
> On Monday, 25 May 2015 at 15:06:45 UTC, Alex Parrill wrote:
>> Hint: Use `cartesianProduct` [1] with three iota ranges to replace the foreachs, and `filter` to replace the if
>>
>> [1] http://dlang.org/phobos/std_algorithm_setops.html#.cartesianProduct
>
> Thank you. Is it possible to replace the loop `foreach` function `each` or `chunkBy` with the auxiliary functions?
>
> import std.stdio, std.algorithm, std.range;
>
> void main() {
>
>     const x = 12, y = 65, z = 50, s = 1435;
>
>     auto a = iota(0, x + 1);
>
>     foreach (idx; cartesianProduct(a, a, a).filter!(i => i[0] * (y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s)) {
>         writeln(idx[0] + idx[1] + idx[2]);
>         writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
>         writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
>         writeln(idx[0], idx[1], idx[2]);
>     }
> }
> -----
> http://rextester.com/HZP96719

import std.algorithm;
import std.range;
import std.stdio;

void main()
{
    const x = 12, y = 65, z = 50, s = 1435;
    auto a = iota(0, x + 1);
    cartesianProduct(a, a, a)
      	.filter!(i => i[0] * (y + 3 * z)
            + i[1] * (y + 2 * z)
            + i[2] * (y + z)
            == s)
      	.each!((idx)
        {
            writeln(idx[0] + idx[1] + idx[2]);
            writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
            writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
            writeln(idx[0], idx[1], idx[2]);
        });
}
May 25, 2015
On Monday, 25 May 2015 at 16:41:35 UTC, Meta wrote:
> import std.algorithm;
> import std.range;
> import std.stdio;
>
> void main()
> {
>     const x = 12, y = 65, z = 50, s = 1435;
>     auto a = iota(0, x + 1);
>     cartesianProduct(a, a, a)
>       	.filter!(i => i[0] * (y + 3 * z)
>             + i[1] * (y + 2 * z)
>             + i[2] * (y + z)
>             == s)
>       	.each!((idx)
>               {
>                   writeln(idx[0] + idx[1] + idx[2]);
>                   writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
>                   writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
>                   writeln(idx[0], idx[1], idx[2]);
>               });
> }

Thanks. I do not even know what `each` support braces.
May 25, 2015
On Monday, 25 May 2015 at 17:05:35 UTC, Dennis Ritchie wrote:
> On Monday, 25 May 2015 at 16:41:35 UTC, Meta wrote:
>> import std.algorithm;
>> import std.range;
>> import std.stdio;
>>
>> void main()
>> {
>>    const x = 12, y = 65, z = 50, s = 1435;
>>    auto a = iota(0, x + 1);
>>    cartesianProduct(a, a, a)
>>      	.filter!(i => i[0] * (y + 3 * z)
>>            + i[1] * (y + 2 * z)
>>            + i[2] * (y + z)
>>            == s)
>>      	.each!((idx)
>>              {
>>                  writeln(idx[0] + idx[1] + idx[2]);
>>                  writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
>>                  writeln(idx[0] * 3 + idx[1] * 2 + idx[2]);
>>                  writeln(idx[0], idx[1], idx[2]);
>>              });
>> }
>
> Thanks. I do not even know what `each` support braces.

`each` doesn't support braces. There are 4 ways to write a function/delegate literal in D (with a few minor variations):

Short form:
function(int i) => i;
(int i) => i
(i) => i
i => i

Long form:
function(int i) { return i; }
(int i) { return i; }
(i) { return i; }
{ return 0; }

http://dlang.org/expression.html#FunctionLiteral
function
May 25, 2015
On Monday, 25 May 2015 at 17:19:27 UTC, Meta wrote:
> `each` doesn't support braces. There are 4 ways to write a function/delegate literal in D (with a few minor variations):
>
> Short form:
> function(int i) => i;
> (int i) => i
> (i) => i
> i => i
>
> Long form:
> function(int i) { return i; }
> (int i) { return i; }
> (i) { return i; }
> { return 0; }
>
> http://dlang.org/expression.html#FunctionLiteral
> function

Thanks.

But why is the solution breaks down when `s = 10000` ? :)

import std.stdio, std.algorithm, std.range;

int c;
const x = 12, y = 65, z = 50, s = 100000;

void solve(Range)(Range r) {
	cartesianProduct(r, r, r).filter!(i => i[0] * (y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;
}

void main() {

    auto a = iota(0, x + 1).array;

    solve(a);

    writefln(`%s total`, c);
}

void dout(Tuple)(Tuple idx) {
    ++c;
}
-----
http://rextester.com/XGDL26042
May 25, 2015
On Monday, 25 May 2015 at 17:52:09 UTC, Dennis Ritchie wrote:
> But why is the solution breaks down when `s = 10000` ? :)
>
> import std.stdio, std.algorithm, std.range;
>
> int c;
> const x = 12, y = 65, z = 50, s = 100000;

Which is it, now? 4 or 5 zeros?

> void solve(Range)(Range r) {
> 	cartesianProduct(r, r, r).filter!(i => i[0] * (y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;
> }
>
> void main() {
>
>     auto a = iota(0, x + 1).array;
>
>     solve(a);
>
>     writefln(`%s total`, c);
> }
>
> void dout(Tuple)(Tuple idx) {
>     ++c;
> }
> -----
> http://rextester.com/XGDL26042

What do you mean it "breaks down"? Your original code doesn't print anything for s = 10_000 or s = 100_000, either.
May 25, 2015
On Monday, 25 May 2015 at 19:16:04 UTC, anonymous wrote:
> On Monday, 25 May 2015 at 17:52:09 UTC, Dennis Ritchie wrote:
>> But why is the solution breaks down when `s = 10000` ? :)
>>
>> import std.stdio, std.algorithm, std.range;
>>
>> int c;
>> const x = 12, y = 65, z = 50, s = 100000;
>
> Which is it, now? 4 or 5 zeros?

No difference!

>> void solve(Range)(Range r) {
>> 	cartesianProduct(r, r, r).filter!(i => i[0] * (y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;
>> }
>>
>> void main() {
>>
>>    auto a = iota(0, x + 1).array;
>>
>>    solve(a);
>>
>>    writefln(`%s total`, c);
>> }
>>
>> void dout(Tuple)(Tuple idx) {
>>    ++c;
>> }
>> -----
>> http://rextester.com/XGDL26042
>
> What do you mean it "breaks down"? Your original code doesn't print anything for s = 10_000 or s = 100_000, either.

Excuse me, this is my blemish! I forgot that the constant `x` depends on `s`. Everything works correctly:

import std.stdio, std.algorithm, std.range;

void solve(Range)(Range r) {
    cartesianProduct(r, r, r).filter!(i => i[0] * (y + 3 * z) + i[1] * (y + 2 * z) + i[2] * (y + z) == s).each!dout;
}

const y = 65, z = 50, s = 100000;
const x = s / (y + z);

void main() {

    auto a = iota(0, x + 1);

    solve(a);
}

auto dout(Tuple)(Tuple idx) {
    writefln(`%s apples`, idx[0] + idx[1] + idx[2]);
    writefln(`%s gingerbread`, idx[0] * 3 + idx[1] * 2 + idx[2]);
    writefln(`%s pharynx tea`, idx[0] * 3 + idx[1] * 2 + idx[2]);
    writefln("Sour: %s; semi-acid: %s; sweet: %s.\n", idx[0], idx[1], idx[2]);
}
-----
http://rextester.com/MMCI9993