Perl Weekly Challenge: Week 344

Challenge 1:

Array From Compute

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

Write a script to add $x to the integer in the array-form.

The array form of an integer is a digit-by-digit representation stored as an array, where the most significant digit is at the 0th index.

Example 1
Input: @ints = (1, 2, 3, 4), $x = 12
Output: (1, 2, 4, 6)
Example 2
Input: @ints = (2, 7, 4), $x = 181
Output: (4, 5, 5)
Example 3
Input: @ints = (9, 9, 9), $x = 1
Output: (1, 0, 0, 0)
Example 4
Input: @ints = (1, 0, 0, 0, 0), $x = 9999
Output: (1, 9, 9, 9, 9)
Example 5
Input: @ints = (0), $x = 1000
Output: (1, 0, 0, 0)

A Raku one-liner. We take the input through command-line arguments. The first argument will be used as the value of $x. The rest will be join()ed up and added to $x. Then the result will be split back up into an array with .comb(). The rest of the code is to print the output in the style of the spec.

my $x = @*ARGS.shift; say q{(}, ($x + @*ARGS.join).comb.join(q{, }), q{)};

(Full code on Github.)

The Perl version is also one line and just slightly longer.

my $x = shift @ARGV; say q{(}, (join q{, }, (split //, ($x + join q{}, @ARGV))), q{)};

(Full code on Github.)

Challenge 2:

Array Formation

You are given two list: @source and @target.

Write a script to see if you can build the exact @target by putting these smaller lists from @source together in some order. You cannot break apart or change the order inside any of the smaller lists in @source.

Example 1
Input: @source = ([2,3], [1], [4])
    @target = (1, 2, 3, 4)
Output: true

Use in the order: [1], [2,3], [4]
Example 2
Input: @source = ([1,3], [2,4])
    @target = (1, 2, 3, 4)
Output: false
Example 3
Input: @source = ([9,1], [5,8], [2])
    @target = (5, 8, 2, 9, 1)
Output: true

Use in the order: [5,8], [2], [9,1]
Example 4
Input: @source = ([1], [3])
    @target = (1, 2, 3)
Output: false

Missing number: 2
Example 5
Input: @source = ([7,4,6])
    @target = (7, 4, 6)
Output: true

Use in the order: [7, 4, 6]

To get the input into the script, we once again resort to using the command-line arguments. The first is the @target and the rest will be the sublists of @source. Each one consists of numbers separated by whitespace. So for instance, the input for example 3 would be "5 8 2 9 1" "9 1" "5 8" "2". The first order of business is to convert those arguments back into arrays.

    my @target = @args.shift.words;
    my @source = @args.map({ [.words] });

We take @target and .join() it into a string.

    my $trg = @target.join;

We also set up a variable to hold the result and initially set it to False.

    my $result = False;

For each permutation of the sublists of @source (found with .permutations())...

    for @source.permutations -> $src {

...we .join() each sublist into a string and then .join() those strings into one big string which is compared to $trg.

        if (@$srcĀ».join).join eq $trg {

If they are equal, we set $result to True and stop processing otherwise we continue on to the next permutation.

            $result = True;
            last;
        }
    }

Once processing is finished, we print $result.

    say $result;

(Full code on Github.)

This is the Perl version. I had to replace permutations() with the permute() function I used in previous challenges but otherwise, the code is pretty similiar to Raku.

my @target = split /\s+/, shift;
my @source = map { [split /\s+/] } @ARGV;

my $trg = join q{}, @target;
my $result = false;

for my $p ( permute(@source) ) {
    my $src = join q{}, map { join q{}, @$_ } @$p;
    if ($src eq $trg) {
        $result = true;
        last;
    }
}

say $result ? "True" : "False";

(Full code on Github.)