Perl Weekly Challenge 186: Zip List and Unicode Makeover

These are some answers to the Week 186 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 Oct. 16, 2022 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.

You are given two lists `@a` and `@b` of same size.

Create a subroutine `sub zip(@a, @b)` that merges the two lists as shown in the example below.

Example:

``````Input:  @a = qw/1 2 3/; @b = qw/a b c/;
Output: zip(@a, @b) should return qw/1 a 2 b 3 c/;
zip(@b, @a) should return qw/a 1 b 2 c 3/;
``````

Zip List in Raku

Raku has a built-in `zip` routine, so we will name `zip-it` our subroutine to avoid any confusion. In addition, Raku has an infix Z operator which performs exactly what is requested in the task. So we will use this operator in the`zip-it` subroutine.

``````sub zip-it (@a, @b) {
return ~ (@a Z @b).flat;
}
my @tests = <1 2 3>, <a b c>;
say zip-it @tests[0], @tests[1];
say zip-it @tests[1], @tests[0];
``````

This script displays the following output:

``````\$ raku ./zip-list.raku
1 a 2 b 3 c
a 1 b 2 c 3
``````

Zip List in Perl

The program iterates over the indices of any of the two lists (which have the same size) and concatenates to the output the corresponding values of both arrays.

``````use strict;
use warnings;
use feature qw/say/;

sub zip  {
my @c = @{\$_[0]};
my @d = @{\$_[1]};
my \$out = "";
for my \$i (0..\$#c) {
\$out = \$out . \$c[\$i] . " " . \$d[\$i] . " " ;
}
return \$out;
}
my @tests = ([<1 2 3>], [<a b c>]);
say zip \$tests[0], \$tests[1];
say zip \$tests[1], \$tests[0];
``````

This script displays the following output:

``````\$ perl ./zip-list.pl
1 a 2 b 3 c
a 1 b 2 c 3
``````

You are given a string with possible unicode characters.

Create a subroutine `sub makeover(\$str)` that replace the unicode characters with ascii equivalent. For this task, let us assume it only contains alphabets.

Example 1:

``````Input: \$str = 'ÃÊÍÒÙ';
Output: 'AEIOU'
``````

Example 2:

``````Input: \$str = 'âÊíÒÙ';
Output: 'aEiOU'
``````

I’m not sure what is meant by “it only contains alphabets,” but the two examples provided only contain vowels in the right alphabetical order. In my implementations, I’ve used the two test cases provided above and added a third test case, just for testing a few more letters, without attempting to satisfy any particular order.

I don’t like very much problems dealing with Unicode because, while I know quite a few things about Unicode, UTF8, and so on, I usually don’t fully understand what is going on at a deeper level. As a result, I often end up trying various things until it works properly, and this is really not my vision of what a programmer should be doing.

Unicode Makeover in Raku

In Raku, we’ll use the built-in samemark routine, which does exactly what we need.

``````sub makeover (\$in) {
return \$in.samemark('a');
}
for 'ÃÊÍÒÙ', 'âÊíÒÙ', 'àçùòîéèûä' -> \$test {
say "\$test -> \t", makeover(\$test);
}
``````

This script displays the following output:

``````\$ raku ./unicode_makeover.raku
ÃÊÍÒÙ ->        AEIOU
âÊíÒÙ ->        aEiOU
àçùòîéèûä ->    acuoieeua
``````

Unicode Makeover in Perl

``````use strict;
use warnings;
use feature 'say';
use utf8;
use Unicode::Normalize;
binmode(STDOUT, ":utf8");

sub makeover {
return join '', map { /(.)/ } map { /(\X)/g } NFD shift;
}

for my \$test ('ÃÊÍÒÙ', 'âÊíÒÙ', 'àçùòîéèûä' ) {
say "\$test -> \t", makeover(\$test);
}
``````

This script displays the following output:

``````\$ perl ./unicode_makeover.pl
ÃÊÍÒÙ ->        AEIOU
âÊíÒÙ ->        aEiOU
àçùòîéèûä ->    acuoieeua
``````

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 23, 2022. And, please, also spread the word about the Perl Weekly Challenge if you can.