PWC 255

PWC 255

I solve both challenges using perl 4.019 on DOSBOX. For comparison, I also solve them using python 1.4 beta on DOSBOX. The Perl solutions also run fine on Perl 5.38. My Python solution to challenge 1 is also forward compatible with python 2.7.18, but my python solution to challenge 2 does not work in python 2.

Challenge 1 (Odd Character)

Links to code: perl4.019 python1.4b

We are given two strings, s and t say, where t is a jumbled version of s plus one extra character. We are asked to find the extra character.

I eschew input validation chores, so I assume that the inputs satisfy the requirements. My approach is to use hashes to count the incidence of each character in s and t, then we compare the hashes to find the element of t whose frequency is higher than that of the same character in s

Here is the perl 4.019 subroutine:

sub odd_character {
 local($s,$t)=@_;
 # ...
 local(%s,%t,$i);
 foreach $i (split(//,$s)) {
  $s{$i}++;
 }
 foreach $i (split(//,$t)) {
  $t{$i}++;
 }
 foreach $i (keys %t) {
  ($t{$i} > $s{$i}) && (return $i);
 }
 return "ERROR";
}

Here is the python 1.4 beta version, pretty much a literal translation:

def odd_character( s, t ):
 in_s={}
 in_t={}
 for i in s:
  try:
   in_s[i] = in_s[i]+1
  except KeyError:
   in_s[i] = 1
 for i in t:
  try:
   in_t[i] = in_t[i]+1
  except KeyError:
   in_t[i] = 1
 for i in in_t.keys():
  if not i in in_s.keys():
   return i
  if in_t[i] > in_s[i]:
   return i
 return "ERROR"

Unlike Perl, Python refuses to allow us to increment a hash entry that has not been defined earlier (throwing a "KeyError" in this version). I use a try .. except block to catch the KeyError exception and create the hash entry the first time. 

Challenge 2 (Most Frequent Word)

Links to code: perl4.019 python1.4b

We are given a paragraph p and a single word s. We are asked to find the most frequent word in the paragraph that is not the same as s

To solve this, I split the paragraph on whitespace and punctuation marks to get a list of words, and then use a hash to count the words, skipping over s. We can then find the most frequent word. In perl 4, I use sort with an appropriate sorting function, while in python I call the max operator.

Here is the perl 4.019 subroutine:

sub most_frequent_word {
 local( $p, $w )=@_;
 local( @p ) = split(/[\s,.!?]+/,$p);
 local( %p, $i );
 foreach $i (@p) {
  $p{$i}++ unless ($i eq $w);
 }
 (sort {$p{$b}<=>$p{$a};}  keys %p)[0];
}

Here is the python equivalent. I can't think of an easy way to avoid a regex (to split the paragraph), so this ends up not being compatible with later versions of python such as python 2, whose regex modules have changed.

def most_frequent_word( p, w ):
 punct=regex.compile("[,.!?]")
 p_nopunct=regsub.gsub(punct," ",p)
 in_p={}
 p_words=string.split(p_nopunct)
 for word in p_words:
  if not word==w:
   try:
    in_p[word]=in_p[word]+1
   except KeyError:
    in_p[word]=1
 mymax=max(in_p.values())
 for word in in_p.keys():
  if (in_p[word]==mymax):
   return word
 return "ERROR!" 

The function regsub.gsub( regex, replacement, string) is the python 1.4 global search and replacement function. It replaces every match of regex in string with replacement. In Python 2 and 3, it is replaced with re.sub with similar syntax.

Comments

Popular posts from this blog

PWC 215

PWC 227

PWC 234