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:
- Even Distribution: Each number must occur an even number of times. If not, forming equal pairs is impossible.
- 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
-
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.
-
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.
-
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.