views:

114

answers:

4

I have a data that looks like this:

3
2
1
5

What I want to get is the "decreasing" cumulative of this data yielding

11
8
6
5
0

What is the compact way of doing that in Perl?

+7  A: 
perl -e '{ my @a = (3,2,1,5); map { $s+=$_ } @a; 
           map { print "$s\n"; $s-= $_ } (@a,0) }'

or

perl -e '{ my @a = (3,2,1,5); my @r = (0); 
           map { $s += $_ ; push @r, $s } reverse @a; 
           print join("\n", reverse @r)."\n" }'

Note: these both require an extra statement my $s=0; using strict.

But may I ask WHY?

DVK
Both of these were tested using http://codepad.org/
DVK
Good answers. Couple of minor details. With `use strict`, you don't need `my $s = 0`; rather, you simply need `my $s`. Also, why void-context `map` rather than good old `for`?
FM
1) Valid point - But I hate uninitialized variables for readability reasons :) 2) No particular technical reason, I just like map :)
DVK
+6  A: 

I am not sure if you can get more compact than @DVK's solution.

#!/usr/bin/perl

use strict; use warnings;
use List::Util qw(sum);

my @array = (3, 2, 1, 5);
my $sum = sum @array;

for my $x ( @array ) {
    print $sum, "\n";
    $sum -= $x;
}

print "0\n";

Combining sum with map:

#!/usr/bin/perl

use strict; use warnings;

use List::Util qw(sum);

my @array = (3, 2, 1, 5);
my $sum = sum @array;

print join("\n", map $sum -= $_, (0, @array)), "\n";
Sinan Ünür
Sinan - why are you sorting the array upfront? You get incorrect answer that way: 11,10,8,5,0. Removing sort will get the result he wants.
DVK
I'm tempted to +1 this for use of List::Util, but to -1 this for waste of cycles on repetitive summation :) +1 it is :)
DVK
@DVK Ooops ... My mind wandered into CDFs ( http://en.wikipedia.org/wiki/Cumulative_distribution_function )
Sinan Ünür
+2  A: 

Here you go

   #!/usr/bin/perl -w
    use strict;
    use List::Util qw (sum);

    my @a = ( 3,2,1,5);

    my $sum = sum(@a);


    foreach ( @a )
    {
        print "$sum ";    
        $sum -= $_;
    }

    print $sum;
Vlad
+1  A: 
perl -e 'print join(", ", reverse map { $s=$s+$_ } reverse qw/3 2 1 5 0/)'
Terence