PWC 254

PWC 254

I do the challenges this week in perl 4.019 on DOSBOX, and for comparison, also in python 1.4 beta on DOSBOX. My perl solutions also run on the current Perl 5.38, In the python case, my challenge 1 solution runs on Python 2.7.18, but my challenge 2 solution does not.

Challenge 1 (Three Power)

Links to code: Perl4.019 Python1.4b

We are given an integer, and asked to verify if it represents the cube of another integer.

The solution is to take the cube root and compare it to its integer portion.

Here is the key perl 4 snippet:

sub three_power {
 local( $n )=@_;
 $n=($n**(1/3));
 $n==sprintf("%d",$n);
}

Here is the python 1.4 beta equivalent:

def three_power(n):
 n=n**(1.0/3.0)
 return (n==int(n))

Challenge 2 (Reverse Vowels)

Links to code: Perl4.019 Python1.4b

We are given a string of alphabets. We are asked to identify which of the elements are vowels, and then to return a string in which the order of the vowel elements is reversed. For example, if 'a' is at index 1, and 'u' at index 3, then the returned string would have 'u' at index 1 and 'a' at index 3. For example, 'Raku' would become 'Ruka'.

The test examples are all in proper case or title case for the returned string (first character uppercase, all others lowercase) so I treat this as part of the requirement.

Here is the key perl 4.019 subroutine:

sub reverse_vowels {
 local(@s)=split(//,$_[0]);
 local(@reverse_vowels)=grep($s[$_] =~ /[aeiouAEIOU]/, 0..$#s);
 @s[@reverse_vowels]=@s[reverse(@reverse_vowels)];
 &ucfirst(&lc(join('',@s)));
}

I first get the array of string elements using split, @s. I use grep to get the indices corresponding to vowels, @reverse_vowels. I then assign the elements at these indices to the vowels with the indices reversed, using array slices. 

@s[@reverse_vowels]=@s[reverse(@reverse_vowels)];

Finally, I join the @s elements to get back a string, lowercase the string, and then uppercase the first element. The built-in lc and ucfirst string operators are not available in this old perl, so I cobble up homemade versions, using the tr operator to convert uppercase alphabets to lowercase, and vice versa.

sub lc {
 local($lc)=$_[0];
 $lc =~ tr/A-Z/a-z/;
 $lc;
}
 
sub ucfirst {
 local($ucfirst)=$_[0];
 substr($ucfirst,0,1) =~ tr/a-z/A-Z/;
 $ucfirst;
}

This was more troublesome in python 1.4 beta, which requires library modules to be loaded to get the necessary regex and string functions. The regex modules do not have the same names as in later python 2, so forward compatibility is broken. Python 1.4 beta on the other hand does have string methods corresponding to lc and ucfirst (string.lower and string.capitalize respectively).

Here is the python 1.4 beta function:

import regex,regsub,string
vowels=regex.compile("[aeiouAEIOU]")

def reverse_vowels(mystr):
 vind=[] #store indices of vowel elements of mystr
 str2arr=[] #store elements of mystr
 for i in range(len(mystr)):
  str2arr.append(mystr[i])
  if ( vowels.match( mystr[i] ) > -1 ):
   vind.append(i)
 vindr=vind[:]
 vindr.reverse()
 #
 for i in range(len(vind)):
  str2arr[vind[i]]=mystr[vindr[i]]
 retval=regsub.gsub(" ","", string.join(str2arr))
 return string.capitalize(string.lower(retval))

I split the string into an array str2arr using a loop, and in the same loop, identify the vowels using a regex match, and store their indices in another array vind. Python 1.4 beta gives -1 if there is no match (not a vowel) and the index of the matching element otherwise (0 for a single-character string), so we have a vowel if the match returns a number greater than -1. To assign the elements at these indices to the vowels in reverse order is more cumbersome than in perl. I first copy vind to another array vindr. I then reverse vindr. I then use a loop through vind to assign the elements of str2arr at each index from vind to the elements of mystr at the corresponding index from vindr.

Finally, I join the elements of str2arr to get a string and capitalize it. This needs a regex to get rid of some spaces with which python pads the string.

regsub.gsub(" ","", string.join(str2arr))

This calls the gsub function from the regsub module to replace spaces " " with nothing "" in the string produced by joining the elements of str2arr (which will be a bug if the original input string contains spaces, but let's ignore that, since the test examples are all single words with no spaces).

 

Comments

Popular posts from this blog

PWC 215

PWC 227

PWC 234