# RogerBW's Blog

The Weekly Challenge 254: Reverse the Power of Three Vowels 04 February 2024

I’ve been doing the Weekly Challenges. The latest involved numerical searching and letter substitution. (Note that this ends today.)

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.

All right, I ignored the positive bit, but so did the test cases. The obvious approach would be to take a cube root, round down to integer, and cube it, but I felt like writing a bisecting search instead. (Newton-Raphson would converge faster, but would probably need floating point.)

Ruby:

``````def threepower(n0)
``````

Apparently zero isn't a power of three (test cases).

``````  if n0 == 0 then
return false
end
``````

This will work for negative numbers too.

``````  n = n0.abs
``````

Set up the extents of the search.

``````  lo = 1
hi = n.div(2)
while true do
``````

Find a new midpoint, and its cube.

``````    t = (lo + hi).div(2)
c = t * t * t
``````

``````    if c == n then
return true
end
``````

Have we converged without an answer?

``````    if lo == t then
return false
end
``````

Otherwise pull the edge of the range into the midpoint and go again.

``````    if c < n then
lo = t
else
hi = t
end
end
end
``````

You are given a string, `\$s`.

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

This is very easy… if you ignore case. So I chose not to. In Raku:

First, a vowelness tester.

``````sub is_vowel(\$c) {
if (\$c ~~ m:i/<[aeiou]>/) {
return True;
} else {
return False;
}
}
``````

Then the main function:

``````sub reversevowels(\$a) {
``````

Break the string into a list. (I don't like subscripted string access, Python-style, though I used it in Python.)

``````    my @p = \$a.comb();
``````

Have a sublist of that with just the vowels, in order.

``````    my @q = @p.grep({is_vowel(\$_)});
``````

Initialise an index to point past the end of that.

``````    my \$qi = @q.elems;
my @o;
``````

For each character:

``````    for @p -> \$c {
``````

If it's a vowel:

``````        if (is_vowel(\$c)) {
``````

Take the last unused vowel from the vowel list.

``````            \$qi--;
my \$nc = @q[\$qi];
``````

Flip it to match the case of the character we're looking at.

``````            if (\$c eq uc(\$c)) {
\$nc = uc(\$nc);
} else {
\$nc = lc(\$nc);
}
``````

``````            @o.push(\$nc);
} else {
``````

If the character is not a vowel, add it as-is.

``````            @o.push(\$c);
}
}
return @o.join('');
}
``````

Full code on github.