Robbie Hatley's Solutions To The Weekly Challenge #254

For those not familiar with "The Weekly Challenge", it is a weekly programming puzzle with two parts, cycling every Sunday. You can find it here:

The Weekly Challenge

This week (2024-01-28 through 2024-02-03) is weekly challenge #254. Its tasks are as follows:

Task 254-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

First of all, I had to think hard whether "Three Power" means "x^3" or "3^x". But the latter would be "3 to the x power", whereas the former is "x to the 3 power", so I think "Three Power" means "x^3".

This is also corroborated by Example #2, which states that 0 is a "Three Power" because "0 = 0^3", not "0 = 3^0" which is false (3^0 = 1). So this problem boils down to "Given an integer x, does there exist an integer r such that r^3 = x?"

There are many ways to solve this problem: Factoring, trial-and-error, subtracting integer portion of cube root from cube root, cubing the integer portion of the cube root, etc.

I initially chose to use a method that's simpler than any of those: If the cube root of $x is an integer, then $x is a perfect cube, else it isn't.

However, I ran into a complicating factor with that approach: C (and hence Perl) fails to correctly implement a**b if a is a negative real number and b is 1/n where n is an odd integer greater than 1 (3, 5, 7...).

So I changed my approach to the following: I first calculate the icr (integer portion of cube root) of x. Then I check to see if icr(x)^3 is equal to x. If it is, $x is a perfect cube, else it's not.

With that in-mind, I created these subs:

# Return the integer portion of the cube root of any integer:
sub icr ($x) {
   my $r = 0;
   if ($x < 0) {--$r until ($r-1)*($r-1)*($r-1) < $x}
   else        {++$r until ($r+1)*($r+1)*($r+1) > $x}
   return $r;
}

# Is a given integer a perfect cube?
sub is_cube ($x) {
   return icr($x)*icr($x)*icr($x) == $x;
}

Robbie Hatley's Perl Solution to The Weekly Challenge 254-1

Task 254-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.
[But keep the case. ~RH]

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"

This problem is quite tricky, as it involves reversing a non-contiguous slice of a word without altering the remaining characters, and while keeping track of case. I used the following approach:

  1. Riffle through the word, recording arrays of these two things for each vowel:
    1. index
    2. vowel
  2. Riffle through the array of vowel indices. For each index, substr the character at that index in the word to an appropriately-cased version of the letter popped from the right end of the vowels array.

Robbie Hatley's Perl Solution to The Weekly Challenge 254-2

That's it for challenge 254; see you on challenge 255!

Comments

Popular posts from this blog

Robbie Hatley's Solutions To The Weekly Challenge #221

Robbie Hatley's Solutions To The Weekly Challenge #239

Robbie Hatley's Solutions To The Weekly Challenge #262