### Perl Weekly Challenge: Week 235

#### Challenge 1:

Remove One

You are given an array of integers.

Write a script to find out if removing ONLY one integer makes it strictly increasing order.

##### Example 1
``````Input: @ints = (0, 2, 9, 4, 6)
Output: true

Removing ONLY 9 in the given array makes it strictly increasing order.
``````
##### Example 2
``````Input: @ints = (5, 1, 3, 2)
Output: false
``````
##### Example 3
``````Input: @ints = (2, 2, 3)
Output: true
``````

This is not a one-liner I'm afraid but it is fairly short and simple.

First we define a flag to note whether we are going in strictly increasing order or not. Initially it is false.

``````my Bool \$increasing = False;
``````

Then setting `\$i` in a range from 0 to the length of `@ints` (which we have populated from command-line arguments) ...

``````for 0 .. @ints.end -> \$i {
``````

...we make a copy of `@ints` and remove the `\$i`th element from it.

``````    my @copy = @ints;
@copy.splice(\$i, 1);
``````

We check if this copy is in strictly increasing order. Originally I did this by comparing `@copy` with yet another copy which had `.sort()` run upon it. If the two were equivalent it would mean increasing order. But it is more efficent to use `[<]` operator instead.

``````    if [<] @copy {
``````

If `@copy` is in increasing order, we can set `\$increasing` to true and stop searching. There may be other viable candidates but we only care if there is at least one.

``````        \$increasing = True;
last;
}
``````

If it wasn't, we go back and try a different copy.

``````}
``````

Regardless of the outcome, we print the value of `\$increasing`.

``````say \$increasing;
``````

(Full code on Github.)

This is the Perl version.

Perl doesn't have specific true and false values so I used 1 and `undef` instead.

``````my \$increasing = undef;

for my \$i (0 .. scalar @ARGV - 1) {
my @copy = @ARGV;
splice @copy, \$i, 1;
``````

As we don't have `[<]` I had to use my previous tactic of comparing the copy to a sorted version of itself. This uses smart matching so I had to add `use experimental qw/ smartmatch /;` at the top of the script to prevent an annoying warning message. Oh and both arguments had to be array references for some reason.

``````    if (\@copy ~~ [sort @copy]) {
\$increasing = 1;
last;
}
}

say \$increasing ? 'true' : 'false';
``````

(Full code on Github.)

#### Challenge 2:

Duplicate Zeros

You are given an array of integers.

Write a script to duplicate each occurrence of ZERO in the given array and shift the remaining to the right but make sure the size of array remain the same.

##### Example 1
``````Input: @ints = (1, 0, 2, 3, 0, 4, 5, 0)
Ouput: (1, 0, 0, 2, 3, 0, 0, 4)
``````
##### Example 2
``````Input: @ints = (1, 2, 3)
Ouput: (1, 2, 3)
``````
##### Example 3
``````Input: @ints = (0, 3, 0, 4, 5)
Ouput: (0, 0, 3, 0, 0)
``````

My plan for solving this one is to go through `@ints` (taken from the command-line arguments as usual.) and copy each element into a new array.

So we need a new array called `@output`.

``````my @output;
``````

Then for each element in `@ints`...

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

...If the current element is a 0, instead of one, two 0s are copied into `@output`.

``````    if \$elem == 0 {
@output.push(| (0, 0));
``````

Otherwise the element is copied into `@output` as-is.

``````    } else {
@output.push(\$elem);
}
``````

If the length of `@output` has become the same as the length of `@ints`, it is time to stop processing.

``````    if @output.elems == @ints.elems {
last;
}
}
``````

Finally, we print the suitably prettyed-up `@output`.

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

(Full code on Github.)

This is the Perl version, a straightforward translation from Raku.

``````my @output;

for my \$elem (@ARGV) {
if (\$elem == 0) {
push @output, 0, 0;
} else {
push @output, \$elem;
}

if (scalar @output == scalar @ARGV) {
last;
}
}

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

(Full code on Github.)