Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
May 25, 2015 Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Parrill | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | 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 Re: Replacing nested loops foreach using map/each/etc | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | 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 |
Copyright © 1999-2021 by the D Language Foundation