Perl Weekly Challenge 254: Reverse Vowels

These are some answers to the Week 254, 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 February 4, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 2: Reverse Vowels

You are given a string, $s.

Write a script to reverse all the vowels (a, e, i, o, u) in the given string.

Example 1

Input: $s = "Raku"
Output: "Ruka"

Example 2

Input: $s = "Perl"
Output: "Perl"

Example 3

Input: $s = "Julia"
Output: "Jaliu"

Example 4

Input: $s = "Uiua"
Output: "Auiu"

Example 4 just above shows us that we cannot simply reverse the vowels, but also need to deal with upper- and lower-case letters. To do this, I decided to reduce the whole input string to lowercase at the start, perform the required letter moves (or, rather, substitutions), and finally to turn the first letter of the result to uppercase (with the tc method in Raku and the ucfirst function in Perl).

Reverse Vowels in Raku

We first turn the input string to lower-case (see above why). Then we use a Regex match to build a list of the vowels in the input string. Then we use a regex substitution to replace vowels in the input words by the same vowels in reverse order (using pop). Finally, we use tc (title case) to capitalize the first letter of the result.

sub reverse-vowels ($in) {
    my $str = $in.lc;
    my @vowels = map { .Str }, $str ~~ m:g/<[aeiou]>/;
    $str ~~ s:g/<[aeiou]>/{pop @vowels}/;
    return $str.tc;
}

for <Raku Perl Julia Uiua> -> $test {
    say "$test \t => ", reverse-vowels $test;
}

This program displays the following output:

$ raku ./reverse-vowels.raku
Raku     => Ruka
Perl     => Perl
Julia    => Jaliu
Uiua     => Auiu

Reverse Vowels in Perl

This is a port to Perl of the Raku program above, using equivalent regular expressions. Please refer to the above sections if you need additional explanations.

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

sub reverse_vowels  {
    my $str = lc shift;
    my @vowels = $str =~ /[aeiou]/g;
    $str =~ s/[aeiou]/pop @vowels/ge;
    return ucfirst $str;
}

for my $test (qw <Raku Perl Julia Uiua>) {
    say "$test \t => ", reverse_vowels $test;
}

This program displays the following output:

$ perl ./reverse-vowels.pl
Raku     => Ruka
Perl     => Perl
Julia    => Jaliu
Uiua     => Auiu

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 February 11, 2024. 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.