### Perl Weekly Challenge: Week 238

#### Challenge 1:

Running Sum

You are given an array of integers.

Write a script to return the running sum of the given array. The running sum can be calculated as sum[i] = num[0] + num[1] + …. + num[i].

##### Example 1
``````Input: @int = (1, 2, 3, 4, 5)
Output: (1, 3, 6, 10, 15)
``````
##### Example 2
``````Input: @int = (1, 1, 1, 1, 1)
Output: (1, 2, 3, 4, 5)
``````
##### Example 3
``````Input: @int = (0, -1, 1, 2)
Output: (0, -1, 0, 2)
``````

Hooray we can do a one-liner again this week!

`\$t` stores the running total. It is initially 0. `.map()` is used to iterate through the command line arguments adding each to the current value of `\$t`. And that's it. The result is a transformed array where each element is the total of itself and all the elements preceding it. The rest of the code is just for outputting the results in a pretty way.

``````my \$t=0;say q{(},@*ARGS.map({\$t+=\$_}).join(q{, }),q{)}
``````

(Full code on Github.)

The Perl version is even shorter because, unlike in Raku, we don't need to initialize `\$t`.

``````say q{(},(join q{, },map{\$t+=\$_}@ARGV),q{)}
``````

(Full code on Github.)

#### Challenge 2:

Persistence Sort

You are given an array of positive integers.

Write a script to sort the given array in increasing order with respect to the count of steps required to obtain a single-digit number by multiplying its digits recursively for each array element. If any two numbers have the same count of steps, then print the smaller number first.

##### Example 1
``````Input: @int = (15, 99, 1, 34)
Output: (1, 15, 34, 99)

15 => 1 x 5 => 5 (1 step)
99 => 9 x 9 => 81 => 8 x 1 => 8 (2 steps)
1  => 0 step
34 => 3 x 4 => 12 => 1 x 2 => 2 (2 steps)
``````
##### Example 2
``````Input: @int = (50, 25, 33, 22)
Output: (22, 33, 50, 25)

50 => 5 x 0 => 0 (1 step)
25 => 2 x 5 => 10 => 1 x 0 => 0 (2 steps)
33 => 3 x 3 => 6 (1 step)
22 => 2 x 2 => 4 (1 step)
``````

To solve this problem in Raku we start by creating a hash that will map the integers provided to the number of steps it takes to reduce them to single-digit numbers.

``````    my %steps;
``````

Then for each integer...

``````    for @ints -> \$int {
``````

...first we have to copy it into another variable `\$n` because `\$int` is immutable.

``````        my \$n = \$int;
``````

We use a variable `\$s` to count the number of steps taken. It is initially set to 0.

``````        my \$s = 0;
``````

Then while `\$n` has more than one digit...

``````        while \$n.chars > 1 {
``````

...we split it into individual digits with `.comb()` and multiply all these digits together with `[*]`. The result becomes the new value of `\$n`.

``````            \$n = [*] (\$n.comb);
``````

And we increment the number of steps taken.

``````            \$s++;
}
``````

Once we are down to a single digit, the original integer and the numbers of steps are added to the `%steps` hash. `\$n` is thrown away; we won't need it.

``````        %steps{\$int} = \$s;
}
``````

Once we have the step count for all the integers, we can sort them into a new array in ascending numerical order by number of steps. When there is a tie, as the spec suggests, we place the smaller integer first.

``````    my @sorted = %steps.keys.sort({ %steps{\$^a} <=> %steps{\$^b} || \$^a > \$^b });
``````

And then we nicely format the results and print them.

``````    say q{(}, @sorted.join(q{, }), q{)};
``````

(Full code on Github.)

The Perl version only has one big difference.

``````my %steps;

for my \$int (@ints) {
my \$n = \$int;
my \$s = 0;
while (length \$n > 1) {
``````

Because we don't have the handy `[*]` operator, we have to split `\$n` into digits and loop through them multiplying them as we go.

``````        my \$t = 1;
my @digits = split //, \$n;
for my \$digit (@digits) {
\$t *= \$digit;
}
``````

The rest is the same.

``````        \$n = \$t;
\$s++;
}
\$steps{\$int} = \$s;
}

my @sorted = sort { \$steps{\$a} <=> \$steps{\$b} || \$a > \$b } keys %steps;

say q{(}, (join q{, }, @sorted), q{)};
``````

(Full code on Github.)