THE WEEKLY CHALLENGE - 249

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

Table of Contents

Intrigued by the idea of crafting solutions in different programming languages? Let’s dive into two fascinating coding challenges!

Code: https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-249/lubos-kolouch


Task 1 - Equal Pairs

The Problem: Imagine you have an array of integers, and your task is to divide this array into pairs where each element is included exactly once, and all elements in a pair are equal. Sounds straightforward, right? But there's a catch – what if it's not always possible?

The Catch: Our challenge is twofold:

  1. Even Distribution: Each number must occur an even number of times. If not, forming equal pairs is impossible.
  2. Order Matters: The pairs should be created in the order of their first appearance in the input array.

Approach & Solutions

1. Perl - Hashes and Array Tricks

Perl, known for its text processing prowess, also excels in handling such tasks. We use a hash to count the occurrences of each element. The trick is to also maintain an array to remember the order of first occurrences. This way, we can create pairs that respect the original order.

Key Perl Concepts:

  • Hashes for frequency counting.
  • Arrays to maintain order.
  • Iterative pair formation.

Perl Code Snippet:

# Count frequencies and track the order of elements
my %freq;
my @order;
foreach my $int (@ints) {
    if (!exists $freq{$int}) {
        push @order, $int;
    }
    $freq{$int}++;
}

2. Python - Elegance with Counters

Python simplifies our task with its Counter class from the collections module. However, we faced a challenge: Counter does not maintain order. We overcame this by iterating through the list, using a set to track which elements we've seen, and a list to store them in order.

Key Python Concepts:

  • Counter for frequency.
  • Sets and lists to preserve order.
  • List comprehensions for concise pair creation.

Python Code Snippet:

# Keep the order of first occurrence
seen = set()
ordered_elements = []
for num in ints:
    if num not in seen:
        seen.add(num)
        ordered_elements.append(num)

3. Raku - The Modern Perl

Raku, formerly known as Perl 6, offers a more streamlined approach. Its Bag class is perfect for counting occurrences, and Raku's inherent capabilities make it easy to maintain the order and create pairs.

Key Raku Concepts:

  • Bag for natural frequency counting.
  • Iterative approach with a modern twist.
  • Maintaining order with Raku's built-in features.

Raku Code Snippet:

# Form pairs in the order of first occurrence
my @pairs;
for %freq.kv -> $num, $count {
    @pairs.append([$num, $num]) for 1..($count div 2);
}

Task 2 - DI String Match

To solve the "DI String Match" problem, we'll develop an algorithm that works efficiently for Perl, Python, and Raku. The algorithm needs to create a permutation of integers from 0 to the length of the input string, following the 'I' and 'D' constraints.

Algorithm Overview

  1. Initialization: Start with two pointers or indices, one at 0 (for 'I') and the other at the length of the string (for 'D'). These pointers will help us assign the appropriate values in the permutation.

  2. Iterate through the String: For each character in the string:

    • If the character is 'I', assign the 'I' pointer value to the current position in the permutation, and increment the 'I' pointer.
    • If the character is 'D', assign the 'D' pointer value to the current position in the permutation, and decrement the 'D' pointer.
  3. Final Element: After processing the string, assign the remaining value (either 'I' or 'D' pointer, as they will be equal) to the last element of the permutation.

The Intricacies of Language-Specific Implementations

While the algorithm's core remains consistent across Perl, Python, and Raku, each language brings its unique flavor.

  • In Perl, the blend of foreach loops and array operations exemplifies the language's text-processing prowess.
  • Python, with its clarity and simplicity, turns the algorithm into an easily readable and maintainable code.
  • Raku, the evolved version of Perl, offers a more streamlined and expressive approach, demonstrating its modern features.

Testing the Waters

Testing is crucial. In Perl, we use Test::More, a core module providing a range of testing facilities. Python's unittest framework offers a similar level of assurance. Raku, keeping its Perl heritage, has a built-in testing framework, making it straightforward to validate our solution.