| 02 February 2024 | Challenge 254 |
Reverse Power
Task 1: Three Power
Submitted by: Mohammad S Anwar
You are given a positive integer, $n.
Write a script to return true if the given integer is a power of three otherwise return false.
Example 1
Input: $n = 27
Output: true
27 = 3 ^ 3
Example 2
Input: $n = 0
Output: true
0 = 0 ^ 3
Example 3
Input: $n = 6
Output: false
Preface
Example 2 is not correct. Though zero is a cube, is not a power of three.
Solution
We divide the given number by three as long as it is evenly dividable by 3 and not less than three. For powers of three and only for powers of three, this procedure will stop at one.
sub is_pow_3 ($n) {
$n /= 3 while $n > 2 && !($n % 3);
$n == 1;
}
See the full solution.
Task 2: Reverse Vowels
Submitted by: Mohammad S Anwar
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"
Preliminary Considerations
The task lists ‘a’,’e’, ‘i’, ‘o’ and ‘u’ as vowels, which means we deal with Latin characters only. However, there are some modifiers that may be applied to (some of) these characters: diaeresis, acute, grave, circumflex, tilde, ring… To spice the task up, we’ll consider modified vowels, too.
Solution
As an exercise I’m going to use aliasing instead of indexing for this task.
Steps to solve the task:
- Split the string into an array
@arrof graphemes made of the canonical decomposition of each character. - Create an array
@vowwhose elements are aliases to the vowel graphemes in@a. - Create another array
@upwhose elements are aliases to the uppercase vowel graphemes in@a. - Assign the vowel graphemes in reverse order and in lowercase to the elements of
@vow. - Transform the elements of
@upto uppercase. - Join the elements of
@arrto a string in canonical composition form.
Since Perl v5.22 aliases may easily be created using the feature 'refaliasing'.
Special attention needs to be paid when assigning new values to aliases in an array.
An assignment to the whole array would cut off the alias relations.
Thus we need to assign values to the individual array elements.
This can be achieved by assigning a list to an array slice consisting of all array elements.
Here is the implementation:
use Unicode::Normalize;
use experimental 'refaliasing';
sub reverse_vowels {
my @arr = NFD(shift) =~ /\X/g;
\(my @vow) = map /[aeiou]/i ? \$_ : (), @arr;
\(my @up) = map /\p{Lu}/ ? \$_ : (), @vow;
@vow[0 .. $#vow] = map lc, reverse @vow;
@up[0 .. $#up] = map uc, @up;
NFC(join '', @arr);
}
See the full solution.