Perl Weekly Challenge 235: Duplicate Zeros

These are some answers to the Week 235, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on September 24, 2023 at 23:59). This blog post offers some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 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)

We don't really know what should happen if keeping the array size leads to the removal of the zero just added. We will assume the added zero is just chopped off, like this:

Input: @ints = (0, 3, 2, 0, 4)
Ouput: (0, 0, 3, 2, 0)

Duplicate Zeros in Raku

The duplicate-zeros subroutine uses the map function to build a new array in which any zero from the input array is repeated and other values are just copied untouched. After that, the subroutine returns a splice of the resulting array having the size of the input array.

sub duplicate-zeros (@in) {
    my @result = map { $_ == 0 ?? |(0, 0) !! $_ }, @in;
    return @result[0..@in.end];
}

for <1 0 2 3 0 4 5 0>,  <1 2 3>, <0 3 0 4 5> -> @test {
    printf "%-18s => ", "@test[]";
    say duplicate-zeros @test;
}

This program displays the following output:

$ raku ./duplicate-zeros.raku
1 0 2 3 0 4 5 0    => (1 0 0 2 3 0 0 4)
1 2 3              => (1 2 3)
0 3 0 4 5          => (0 0 3 0 0)

Duplicate Zeros in Perl

This Perl program does the same thing as the above Raku program. Please refer to the above section for any explanation.

use strict;
use warnings;
use feature 'say';

sub duplicate_zeros {
    my @result = map { $_ == 0 ? (0, 0) : $_ } @_;
    return @result[0..$#_];
}

for my $test ([<1 0 2 3 0 4 5 0>], 
    [<1 2 3>], [<0 3 0 4 5>]) {
    printf "%-18s => ", "@$test";
    say join " ", duplicate_zeros @$test;
}

This program displays the following output:

$ perl ./duplicate-zeros.pl
1 0 2 3 0 4 5 0    => 1 0 0 2 3 0 0 4
1 2 3              => 1 2 3
0 3 0 4 5          => 0 0 3 0 0

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on October 1, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.