November 06, 2014
On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:
> I have rectangular forward range of forward ranges (not arrays):
> [
>   [a11, a12, ... a1N],
>   [a21, a22, ... a2N],
>   ...
>   [aM1, aM2, ... aMN]
> ]
>
> I need lazy forward range:
> [
>  a11 + a21 + ... aM1,
>  a12 + a22 + ... aM2,
>  ...
>  a1N + a2N + ... aMN
> ]
> Range of sum elements of every columns;
>
> M, N - runtime values;
>
> Is there a way to do this using only Phobos algorithms and range functions?

nasty inefficient solution, but might be ok if your ranges have cheap popFront:


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

void main()
{
    auto M = 3;
    auto N = 10;

    //generate a RangeOfRanges for testing
    auto ror = iota(1, M+1)
                   .map!(l => iota(N)
                                  .map!(e => e * l^^2));

    auto rorFlat = ror.joiner;
    iota(N)
        .map!(i => rorFlat.save.drop(i).stride(N))
        .map!sum.writeln;
}
November 06, 2014
On Thursday, 6 November 2014 at 22:02:09 UTC, John Colvin wrote:
> On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:
>> I have rectangular forward range of forward ranges (not arrays):
>> [
>>  [a11, a12, ... a1N],
>>  [a21, a22, ... a2N],
>>  ...
>>  [aM1, aM2, ... aMN]
>> ]
>>
>> I need lazy forward range:
>> [
>> a11 + a21 + ... aM1,
>> a12 + a22 + ... aM2,
>> ...
>> a1N + a2N + ... aMN
>> ]
>> Range of sum elements of every columns;
>>
>> M, N - runtime values;
>>
>> Is there a way to do this using only Phobos algorithms and range functions?
>
> Can I get random access in one or both dimensions?

with random access along N:

iota(N).map!((i) => ror.transversal(i).sum())
November 06, 2014
On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:
> I have rectangular forward range of forward ranges (not arrays):
> [
>   [a11, a12, ... a1N],
>   [a21, a22, ... a2N],
>   ...
>   [aM1, aM2, ... aMN]
> ]
>
> I need lazy forward range:
> [
>  a11 + a21 + ... aM1,
>  a12 + a22 + ... aM2,
>  ...
>  a1N + a2N + ... aMN
> ]
> Range of sum elements of every columns;
>
> M, N - runtime values;
>
> Is there a way to do this using only Phobos algorithms and range functions?

this should be a textbook case for std.range.transposed, but I can't seem to get it to work.
November 07, 2014
On Thursday, 6 November 2014 at 22:40:58 UTC, John Colvin wrote:
> this should be a textbook case for std.range.transposed, but I can't seem to get it to work.

Ah, I didn't know this existed. Apparently it's not yet released, that's why it's not in the official documentation.

With DMD and Phobos from git:

    void main(string[] args)
    {
        import std.stdio: writeln;
        import std.range: transposed;
        import std.algorithm: map, sum;

        int[][] input = new int[][2];
        input[0] = [1, 2, 3, 4];
        input[1] = [5, 6, 7, 8];
        writeln(input);

        auto sums = input
                .transposed
                .map!(a => a.sum);
        writeln(sums);
    }

Output:

    [[1, 2, 3, 4], [5, 6, 7, 8]]
    [6, 8, 10, 12]
November 07, 2014
Marc Schütz:

>         int[][] input = new int[][2];
>         input[0] = [1, 2, 3, 4];
>         input[1] = [5, 6, 7, 8];
>         writeln(input);
>
>         auto sums = input
>                 .transposed
>                 .map!(a => a.sum);
>         writeln(sums);
>     }
>
> Output:
>
>     [[1, 2, 3, 4], [5, 6, 7, 8]]
>     [6, 8, 10, 12]

Jack specified:

> I have rectangular forward range of forward ranges (not arrays):

You "input" range is not just a Forward Range.

And by the way, your array literal can be written more simply like this:

int[][2] input = [[1, 2, 3, 4], [5, 6, 7, 8]];

Bye,
bearophile
November 07, 2014
Marc Schütz:

>         auto sums = input
>                 .transposed
>                 .map!(a => a.sum);

And that part is better written:

.map!sum;

I also suggest to align the leading dot to the precedent line:

        auto sums = input
                    .transposed
                    .map!(a => a.sum);

Bye,
bearophile
November 07, 2014
On Friday, 7 November 2014 at 10:58:58 UTC, Marc Schütz wrote:
> On Thursday, 6 November 2014 at 22:40:58 UTC, John Colvin wrote:
>> this should be a textbook case for std.range.transposed, but I can't seem to get it to work.
>
> Ah, I didn't know this existed. Apparently it's not yet released, that's why it's not in the official documentation.
>
> With DMD and Phobos from git:
>
>     void main(string[] args)
>     {
>         import std.stdio: writeln;
>         import std.range: transposed;
>         import std.algorithm: map, sum;
>
>         int[][] input = new int[][2];
>         input[0] = [1, 2, 3, 4];
>         input[1] = [5, 6, 7, 8];
>         writeln(input);
>
>         auto sums = input
>                 .transposed
>                 .map!(a => a.sum);
>         writeln(sums);
>     }
>
> Output:
>
>     [[1, 2, 3, 4], [5, 6, 7, 8]]
>     [6, 8, 10, 12]

http://dlang.org/phobos-prerelease/std_range.html#.transposed

yeah it works find for arrays, but it needs assignable elements.
1 2
Next ›   Last »