# Perl Weekly Challenge 254.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 254.

``````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
``````

(I interpret power of three as \$n**3, not as 3**\$n; otherwise I guess example 2 would be wrong.) An interesting solution would be to find the factors of the number and then check that their multiplicity is a multiple of three. But a quick and dirty solution is to simply take the cubic root, round it to an integer and check its third power equals the original number. This yields a simple oneliner.

Examples:

``````perl -MPOSIX=lround -E 'for(@ARGV){say "\$_ -> ", \$_==lround(\$_**(1/3))**3?"True":"False"}' 27 0 6
``````

Results:

``````27 -> True
0 -> True
6 -> False
``````

Curiously, the code above fails for negative numbers:

``````perl -MPOSIX=lround -E 'for(@ARGV){say "\$_ -> ", \$_==lround(\$_**(1/3))**3?"True":"False"}' -- -27
``````

Results:

``````-27 -> False
``````

The reason is that fractional powers of negative numbers are tricky. The solution is trivial, as (-1)**3=(-1); I simply take the absolute value.

``````perl -MPOSIX=lround -E 'for(@ARGV){say "\$_ -> ", abs(\$_)==lround(abs(\$_)**(1/3))**3?"True":"False"}
' -- -27
``````

Results:

``````-27 -> True
``````

The full code is:

`````` 1  # Perl weekly challenge 254
2  # Task 1:  Three Power
3  #
5  use v5.36;
6  use POSIX qw(lround);
7  die <<~"FIN" unless @ARGV;
8      Usage: \$0 N1 [N2...]
9      to check if the integers N1 N2... are cubes
10      FIN
11  for(@ARGV){
12      warn("\$_ not integer"),next unless \$_ == lround(\$_);
13      say "\$_ -> ", abs(\$_)==lround(abs(\$_)**(1/3))**3?"True":"False";
14  }
``````

Examples:

``````./ch-1.pl 27 0 6 -27
``````

Results:

``````27 -> True
0 -> True
6 -> False
-27 -> True
``````

``````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"
``````

I can split the string into an array, make an array of the indices of its vowels and use it to assign the reversed vowels to the positions occupied by the original vowels. To be consistent with the examples, I `lc` the input and `ucfirst` the output. This yields a one and a half liner, assuming ASCII input.

Examples:

``````perl -E '
for(@ARGV){@x=split "", lc \$_; @i=grep {\$x[\$_]=~/[aeiou]/}(0..@x-1); @x[@i]=reverse @x[@i];
say "\$_ -> ", ucfirst join "", @x;}
' Raku Perl Julia Uiua
``````

Results:

``````Raku -> Ruka
Perl -> Perl
Julia -> Jaliu
Uiua -> Auiu
``````

The full code follows:

`````` 1  # Perl weekly challenge 254
2  # Task 2:  Reverse Vowels
3  #
5  use v5.36;
6  die <<~"FIN" unless @ARGV;
7      Usage: \$0 W1 [W2..]
8      to reverse the vowels in the words W1 W2...
9      FIN
10  for(@ARGV){
11      my @all = split "", lc \$_;
12      my @vowel_indices=grep {\$all[\$_]=~/[aeiou]/} 0..@all-1;
13      @all[@vowel_indices]=reverse @all[@vowel_indices];
14      my \$out=ucfirst join "", @all;
15      say "\$_ -> \$out";
16  }
``````

Example:

``````./ch-2.pl Raku Perl Julia Jaiu Uiua
``````

Results:

``````Raku -> Ruka
Perl -> Perl
Julia -> Jaliu
Jaiu -> Juia
Uiua -> Auiu
``````

/;

Written on January 29, 2024