The Bear's Den

Enter at your own risk

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:

  1. Split the string into an array @arr of graphemes made of the canonical decomposition of each character.
  2. Create an array @vow whose elements are aliases to the vowel graphemes in @a.
  3. Create another array @up whose elements are aliases to the uppercase vowel graphemes in @a.
  4. Assign the vowel graphemes in reverse order and in lowercase to the elements of @vow.
  5. Transform the elements of @up to uppercase.
  6. Join the elements of @arr to 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.