TL;DR

On with TASK #2 from The Weekly Challenge #163. Enjoy!

# The challenge

You are given a list of positive numbers, @n.

Write a script to find out the summations as described below.

Example 1

Input: @n = (1, 2, 3, 4, 5)
Output: 42

1 2 3  4  5
2 5  9 14
5 14 28
14 42
42

The nth Row starts with the second element of the (n-1)th row.
The following element is sum of all elements except first element of previous row.
You stop once you have just one element in the row.


Example 2

Input: @n = (1, 3, 5, 7, 9)
Output: 70

1 3  5  7  9
3  8 15 24
8 23 47
23 70
70


# The questions

What should we do if the list is empty?

Anybody has the formula for this? No? Well, I had to ask.

# The solution

I played a bit with the idea of finding the formula for calculating how many times each individual element in the original array contributed to the end result. Alas, I did not land on anything too elegant and my brute force beast was screaming inside, so here we go in Perl:

#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';

say summations(@ARGV);

sub summations (@n) {
for (2 .. $#n) {$n[$_] +=$n[$_ - 1] for$_ .. $#n } return$n[-1];
}


The input array (which is actually a copy of the input data) is used to do all calculations. The outer loop takes care of â€śgoing forwardâ€ť in it, while the inner loop takes care to do the summations. Thereâ€™s a nice simmetry in how the calculation can be arranged; I like the symmetry, but the readability is terrible.

Whatever.

I discovered that this could be translated into Raku in a pretty straightforward way, so why not?

#!/usr/bin/env raku
use v6;
sub MAIN (*@n) { put summations(@n) }

sub summations (@n is copy) {
for 2 .. @n.end { @n[$_] += @n[$_ - 1] for \$_ .. @n.end }
return @n[*-1];
}


Cheers and stay safe!

Comments? Octodon, , GitHub, Reddit, or drop me a line!