Perl Weekly Challenge: Week 261

Challenge 1:

Element Digit Sum

You are given an array of integers, @ints.

Write a script to evaluate the absolute difference between element and digit sum of the given array.

Example 1
Input: @ints = (1,2,3,45)
Output: 36

Element Sum: 1 + 2 + 3 + 45 = 51
Digit Sum: 1 + 2 + 3 + 4 + 5 = 15
Absolute Difference: | 51 - 15 | = 36
Example 2
Input: @ints = (1,12,3)
Output: 9

Element Sum: 1 + 12 + 3 = 16
Digit Sum: 1 + 1 + 2 + 3 = 7
Absolute Difference: | 16 - 7 | = 9
Example 3
Input: @ints = (1,2,3,4)
Output: 0

Element Sum: 1 + 2 + 3 + 4 = 10
Digit Sum: 1 + 2 + 3 + 4 = 10
Absolute Difference: | 10 - 10 | = 0
Example 4
Input: @ints = (236, 416, 336, 350)
Output: 1296

A Raku one-liner:

(@*ARGS.sum - @*ARGS.map({$_.comb.sum}).sum).abs.say

We take all the command-line arguments as input. .sum() gives us the element sum easy-peasy. Calculating the digit sum is a bit more involved. First we use .map() to transform each element of input by splitting it into digits with .comb() and adding the digits together with .sum(). Then we call .sum() again on the whole array to get the digit sum. Finally, the digit sum is subtracted from the element sum and the result is run through .abs() to get the absolute difference. This is printed out with .say().

(Full code on Github.)

For perl we need to provide our own sum() function. With that, it is also one line.

say abs(sum(@ints) - sum(map { sum(split //, $_) } @ints));

(Full code on Github.)

Challenge 2:

Multiply by Two

You are given an array of integers, @ints and an integer $start.

Write a script to do the followings:

a) Look for $start in the array @ints, if found multiply the number by 2
b) If not found stop the process otherwise repeat

In the end return the final value.

Example 1
Input: @ints = (5,3,6,1,12) and $start = 3
Output: 24

Step 1: 3 is in the array so 3 x 2 = 6
Step 2: 6 is in the array so 6 x 2 = 12
Step 3: 12 is in the array so 12 x 2 = 24

24 is not found in the array so return 24.
Example 2
Input: @ints = (1,2,4,3) and $start = 1
Output: 8

Step 1: 1 is in the array so 1 x 2 = 2
Step 2: 2 is in the array so 2 x 2 = 4
Step 3: 4 is in the array so 4 x 2 = 8

8 is not found in the array so return 8.
Example 3
Input: @ints = (5,6,7) and $start = 2
Output: 2

2 is not found in the array so return 2.

We get $start as the first and @ints as the subsequent command-line parameters. We begin by copying $start to a new variable. This is because function parameters (including parameters to MAIN()) are immutable and we are going to need to change it. I chose to call the new variable $end.

my $end = $start;

Following the spec, we go through the elements of @ints and if $end matches one, we double its' value. If $end doesn't match, we will fall through the loop.

for 0 .. @ints.end -> $i {
    if ($end == @ints[$i]) {
        $end *= 2;
    }
}

Finally, we print whatever the value of $end has become, if indeed it has changed at all.

say $end;

(Full code on Github.)

The Perl version is similar except we can work directly on $start as it is not immutable.

for my $i (0 .. scalar @ints - 1) {
    if ($start == $ints[$i]) {
        $start *= 2;
    }
}

say $start;

(Full code on Github.)