The weekly challenge 254 - Task 2: Reverse Vowels

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-254/#TASK2
 3 #
 4 # Task 2: Reverse Vowels
 5 # ======================
 6 #
 7 # You are given a string, $s.
 8 #
 9 # Write a script to reverse all the vowels (a, e, i, o, u) in the given string.
10 #
11 ## Example 1
12 ##
13 ## Input: $s = "Raku"
14 ## Output: "Ruka"
15 #
16 ## Example 2
17 ##
18 ## Input: $s = "Perl"
19 ## Output: "Perl"
20 #
21 ## Example 3
22 ##
23 ## Input: $s = "Julia"
24 ## Output: "Jaliu"
25 #
26 ## Example 4
27 ##
28 ## Input: $s = "Uiua"
29 ## Output: "Auiu"
30 #
31 ############################################################
32 ##
33 ## discussion
34 ##
35 ############################################################
36 #
37 # Let's first turn the string into an array of characters. Then
38 # let's collect the position of all vowels (and whether or not
39 # they were uppercase). Then we can walk through all vowels and
40 # write them to their new location in the correct (uppwer/lower)
41 # case.
42 
43 use strict;
44 use warnings;
45 
46 reverse_vowels("Raku");
47 reverse_vowels("Perl");
48 reverse_vowels("Julia");
49 reverse_vowels("Uiua");
50 
51 sub reverse_vowels {
52    my $s = shift;
53    print "Input: \"$s\"\n";
54    my @chars = split //, $s;
55    my @vowels = ();
56    my @indices = ();
57    foreach my $i (0..$#chars) {
58       if(is_vowel($chars[$i])) {
59          push @vowels, [ $i, $chars[$i], is_upper($chars[$i]) ];
60          unshift @indices, $i;
61       }
62    }
63    foreach my $j (0..$#vowels) {
64       my ($old_index, $char, $is_upper) = @{ $vowels[$j] };
65       my $new_index = $indices[$j];
66       my $new_char = $char;
67       if($is_upper) {
68          $new_char = uc($new_char);
69       } else {
70          $new_char = lc($new_char);
71       }
72       $chars[$new_index] = $new_char;
73    }
74    $s = join("", @chars);
75    print "Output: \"$s\"\n";
76 
77 }
78 
79 sub is_vowel {
80    my $char = shift;
81    my $vowels = { "a" => 1, "e" => 1, "i" => 1, "o" => 1, "u" => 1 };
82    return $vowels->{lc($char)};
83 }
84 
85 sub is_upper {
86    my $char = shift;
87    return $char eq uc($char);
88 }