Weekly Challenge 254
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: Three Power
Task
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.
My solution
There are two things to consider when doing this task.
- Floating point math is not always going to give you the result you want. Julia Evans makes an excellent blog post about why 0.1 + 0.2 is not 0.3.
- Python sometimes treats the cube root of a negative number as a complex number. I can't seem to find a better reference than this Stack Exchange post.
With that in mind, we know we can get the approximate cube root by applying the function n (1รท3), written as n ** (1/3)
in code. I do this, round the number to the nearest integer, and then check if that number cubed is the original number.
To get around the negative number issue, I take the absolute value.
def three_power(n: int) -> bool:
i = round(abs(n) ** (1/3))
return i ** 3 == abs(n)
Examples
$ ./ch-1.py 27
true
$ ./ch-1.py 0
true
$ ./ch-1.py 6
false
$ ./ch-1.py -8
true
Task 2: Reverse Vowels
Task
You are given a string, $s
.
Write a script to reverse all the vowels (a
, e
, i
, o
, u
) in the given string.
My solution
This is one of those tasks where the Python and Perl versions are slightly different. This is because in Python strings are immutable (i.e. cannot be changed). This has the upside that strings are iterable.
The first thing I do is convert the string to lower case, and extract all the vowels into a list.
def reverse_vowels(s: str) -> str:
s = s.lower()
vowel_list = [c for c in s if c in 'aeiou']
I then loop through each letter of the string. If the letter is a vowel, I pop the last value off the vowel_list
list and add it to the new_string
variable. If it isn't, I add the character as is.
new_string = ''
for c in s:
if c in 'aeiou':
new_string += vowel_list.pop()
else:
new_string += c
Finally I return the string with the first letter capitalized.
return new_string.capitalize()
As I mentioned, the Perl code is slightly different. For this code, I loop through each position in the string. If the letter at that position is a vowel, then I replace it. substr
can be used as a l-value in Perl
for my $pos ( 0 .. length($s) - 1 ) {
if ( substr( $s, $pos, 1 ) =~ /[aeiou]/ ) {
substr( $s, $pos, 1 ) = pop(@vowel_list);
}
}
Examples
$ ./ch-2.py Raku
Ruka
$ ./ch-2.py Perl
Perl
$ ./ch-2.py Julia
Jaliu
$ ./ch-2.py Uiua
Auiu
Top comments (0)