THE WEEKLY CHALLENGE - 235

https://theweeklychallenge.org/blog/perl-weekly-challenge-235/

Table of Contents

Task 1 - Remove One

Introduction

Modifying a data structure to achieve a specific order or pattern is a common theme in algorithmic challenges. The "Remove One" problem brings a unique twist to this idea. In this article, we'll explore solutions in Perl, Python, and Raku, diving deep into the logic and language-specific implementations.

Problem Statement

Given an array of integers, can you transform it into a strictly increasing order by removing just one integer?

Perl Solution

Perl offers powerful array manipulation functions that can simplify many tasks. Here's a concise solution using Perl:

sub can_be_made_increasing {
    my @ints = @_;
    my $count = 0;
    for my $i (1..$#ints) {
        if ($ints[$i] <= $ints[$i-1]) {
            $count++;
            return 0 if $count > 1;
            return 0 if $i > 1 && $ints[$i] <= $ints[$i-2];
        }
    }
    return 1;
}

Python Solution

Python's expressive syntax and powerful standard library make it ideal for such problems:

from typing import List

def can_be_made_increasing(ints: List[int]) -> bool:
    count = 0
    for i in range(1, len(ints)):
        if ints[i] <= ints[i-1]:
            count += 1
            if count > 1 or (i > 1 and ints[i] <= ints[i-2]):
                return False
    return True

Raku Solution

Raku (formerly known as Perl 6) boasts expressive syntax and robust built-in functions that make tasks like these quite straightforward:

sub can-be-made-increasing(@ints) {
    my $count = 0;
    for 1..^@ints.elems -> $i {
        if @ints[$i] <= @ints[$i-1] {
            $count++;
            return False if $count > 1;
            return False if $i > 1 && @ints[$i] <= @ints[$i-2];
        }
    }
    return True;
}

Conclusion

The "Remove One" problem serves as a great exercise in understanding array manipulations and iterative checks. Whether you're using Perl's array manipulation prowess, Python's comprehensibility, or Raku's expressiveness, understanding the underlying logic is key.


Task 2 - Duplicate Zeros

Task: Given an array of integers, we need to duplicate each occurrence of ZERO in the given array, shift the remaining elements to the right, but ensure the size of the array remains the same.

Solution

For this task, we'll use a two-step approach:

  1. Count the number of zeros in the array.
  2. Start from the end of the array, move towards the front, and adjust the positions of elements accordingly based on the count of zeros.
Perl

In Perl, we utilize the grep function to count the zeros. Then, we use a loop to traverse the array in reverse and duplicate the zeros:

my $zeros = grep { $_ == 0 } @ints;

for (my $i = $#ints; $i >= 0 && $zeros > 0; $i--) {
    if ($i + $zeros < @ints) {
        $ints[$i + $zeros] = $ints[$i];
    }
    if ($ints[$i] == 0) {
        $zeros--;
        if ($i + $zeros < @ints) {
            $ints[$i + $zeros] = 0;
        }
    }
}
Python

In Python, we use the count method to count the zeros. The subsequent logic is similar to the Perl approach:

zeros = ints.count(0)
i = len(ints) - 1

while zeros > 0:
    if i + zeros < len(ints):
        ints[i + zeros] = ints[i]
    if ints[i] == 0:
        zeros -= 1
        if i + zeros < len(ints):
            ints[i + zeros] = 0
    i -= 1
Raku

In Raku, we employ the grep method to count the zeros. The remaining logic closely mirrors the Perl and Python solutions:

my $zeros = @ints.grep(0).elems;
my $i = @ints.elems - 1;

while $zeros > 0 {
    if $i + $zeros < @ints.elems {
        @ints[$i + $zeros] = @ints[$i];
    }
    if @ints[$i] == 0 {
        $zeros--;
        if $i + $zeros < @ints.elems {
            @ints[$i + $zeros] = 0;
        }
    }
    $i--;
}

Conclusion

By employing a simple two-step strategy, we can effectively solve the "Duplicate Zeros" task in multiple programming languages. The core logic remains consistent across Perl, Python, and Raku, highlighting the universality of the solution.