I’ve been doing the Weekly
Challenges. The
latest
involved numerical searching and letter substitution. (Note that this
ends today.)
Task 1: Three Power
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
Is it the answer?
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
Task 2: Reverse Vowels
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);
}
Add it to the output.
@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.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.