11 June 2009

Enhancing my own skills

Ok so it's time to start again this blog with less personal messages and more professional ones, since anyway I'm not that sort of guy that talks about its life to everybody (even if this first sentence IS, in fact, exactly what I hate to do).

I've recently subscribed to the TopCoder website (you'll find a link to it on your right), following an advice from a Google recruiter that called me two or three days ago. I won't give the details on the call itself, but you may already know that you need very good and precise skills to work at Google; some of which you will need to resolve problems found on TopCoder too.

So I started to look at the problem you can find there, and resolved already a few ones. I wanted to post this message in order to give my answer to one of the first Algorithm problem, named "Inv 2001 R1", difficulty 250. On TopCoder, each problem has a difficulty score, the higher the score, the harder the problem. I did not see any problem having a score above 1000, but I surely will encounter a few (or a lot) of them while resolving each problem one after the other.

Now let's see what the problem is all about. Ho, and by the way, I'm coding in Java.

 
TopCoder has decided to automate the process of assigning problem difficulty levels to problems.  TopCoder developers have concluded that problem difficulty is related only to the Average Word Length of Words in the problem statement:

If the Average Word Length is less than or equal to 3,  the problem is a 250 point problem.
If the Average Word Length is equal to 4 or 5, the problem is a 500 point problem.
If the Average Word Length is greater than or equal to 6, the problem is a 1000 point problem.

The problem here comes from the fact that a word is determined by the fact that:

  • it contains only letters,
  • it may end with a single period,
  • the period does not count in the number of letters used to calculate the Average Word Length (AWL).

It is quite easy, in Java, to do this problem, since we already have all the tools needed to split the given string, and check if an element is a word. Here is the code:

 
public class HowEasy {
 public int pointVal(String problemStatement) {
  if (problemStatement == null) {
   return 0;
  }
  
  String[] words = problemStatement.split(" ");
  long wordCount = 0;
  long lettersCount = 0;
  for (String word : words) {
   if (word.matches("[a-zA-Z]+.?")) {
    lettersCount += word.length();
    if (word.endsWith(".")) {lettersCount--;}
    wordCount++;
   }
  }
  
  if (wordCount > 0) {
   long avgWordLength = lettersCount/wordCount;
   
   if (avgWordLength < 4) {
    return 250;
   } else if (avgWordLength < 6) {
    return 500;
   } else {
    return 1000;
   }
  }
  
  return 250;
 }
} 

At first, I made a Map containing the values 250, 500, 1000 associated to the corresponding min and max AWL that were identifying the scores, but it was a bit too much for this simple code so I left them "as-is" in the code.

Now, as I said, using Java simplifies a lot the code. Here is how the given string is splitted:

String[] words = problemStatement.split(" ");

...and here is how each element is checked:

if (word.matches("[a-zA-Z]+.?")) {
   ...
}

The rest of the code is quite simple and does not need any explanation.

No comments: