Blog of a Filipino Developer about C#, VB.NET, ASP.NET, Java, PHP, SQL Server, MySql and Oracle RSS 2.0
 Wednesday, January 03, 2007

We had a programming quiz couple of weeks back at Devpinoy.org.. there where 5 people who dared to take on the quiz but sadly nobody got the correct answer after two rounds of testing(i guess i was pretty strict with my test cases) in the end i decided to just give the prize to the person who got the most correct program(15 out of 17 test cases). All in all it was a fun event...

anyway, i decided to post my answer to the quiz that i gave so that people could see how i solved the quiz(btw, this is not perfectly refactored so don't whine if you see some code smells in it...)

The Test Case

using System;
using System.Collections.Generic;
using System.Text;

using NUnit;
using NUnit.Framework;
using System.Diagnostics;

namespace KeithRull.BrainSharpeners
{
   [TestFixture]
   public class TestWordCount
   {
      private WordCount _wordCount;
      [SetUp]
      public void SetUp()
      {
         _wordCount = new WordCount();
      }

      [Test]
      public void Test1()
      {
         string phraseToEvaluate = "this is a long text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test2()
      {
         string phraseToEvaluate = "\"this is a long text consist of different words.\"";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(1, count);
      }

      [Test]
      public void Test3()
      {
         string phraseToEvaluate = "this \"is a long\" text consist \"of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(7, count);
      }

      [Test]
      public void Test4()
      {
         string phraseToEvaluate = "\"this is a long text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test5()
      {
         string phraseToEvaluate = "this is a long text consist of different words.\"";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test6()
      {
         string phraseToEvaluate = "\"\"this is a long text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test7()
      {
         string phraseToEvaluate = "this is a long text consist of different words.\"\"";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test8()
      {
         string phraseToEvaluate = "this is a long text\"\" consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test9()
      {
         string phraseToEvaluate = "this is a long text \"\" consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test10()
      {
         string phraseToEvaluate = "this is a long text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test11()
      {
         string phraseToEvaluate = "this is a long text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(9, count);
      }

      [Test]
      public void Test12()
      {
         string phraseToEvaluate = "";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(0, count);
      }

      [Test]
      public void Test13()
      {
         string phraseToEvaluate = "\"this is a long\"\" text consist of different words.\"";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(2, count);
      }

      [Test]
      public void Test14()
      {
         string phraseToEvaluate = "this is a long\"text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(8, count);
      }

      [Test]
      public void Test15()
      {
         string phraseToEvaluate = "\"this is a long\"\"text consist of different words.\"";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(2, count);
      }

      [Test]
      public void Test16()
      {
         string phraseToEvaluate = " this is a long\"\"text consist of different words.";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(8, count);
      }

      [Test]
      public void Test17()
      {
         string phraseToEvaluate = " this is a long\"\"text consist of different words. ";
         int count = _wordCount.CountNumberOfWordsFrom(phraseToEvaluate);

         Assert.AreEqual(8, count);
      }
   }
}

My Solution

using System;
using System.Collections.Generic;
using System.Text;

namespace KeithRull.BrainSharpeners
{
   /*
   Given a sentence or phrase, return all the words that exist in a phrase. 
   Each word is delimited by a space. NOTE that words that are wrapped in quotes ("") are 
   considered one word. Oh, and no, you can't use built in string library functions like Split.

   * */


   class WordCount
   {
      const char CHAR_DoubleQuote = '"';
      const char CHAR_WhiteSpace = ' ';
      public int CountNumberOfWordsFrom(string phrase)
      {
         int count = 0;
         string lastWord = string.Empty;
         bool jumped = false;

         string phraseToEvaluate = Trim(phrase);
         int phraseLenght = phraseToEvaluate.Length;
         if (phraseLenght != 0)
         {
            char[] phraseCharArray = ConvertToCharArrayFrom(phraseToEvaluate);
            for (int currentIndex = 0; currentIndex < phraseLenght; currentIndex++)
            {
               char lookUpChar = phraseCharArray[currentIndex];
               if (IsWhiteSpace(lookUpChar)) {
                  if (IsValidWord(lastWord)) {
                     count++;
                  }
                  lastWord = string.Empty;
                  jumped = false;
               }
               else if (IsDoubleQuote(lookUpChar))
               {
                  if (jumped) count++;

                  jumped = false;

                  int quotePairIndex = 0;
                  int nextIndex = currentIndex + 1;
                  quotePairIndex = FindCharIndex(phraseCharArray, CHAR_DoubleQuote, nextIndex);
                  if ((nextIndex != quotePairIndex) && (quotePairIndex != -1)) {
                     if (quotePairIndex <= phraseLenght) {
                        lastWord = GetSubStringFromArray(phraseCharArray, currentIndex,quotePairIndex);
                        jumped = true;
                        currentIndex = quotePairIndex;
                     }
                  }
               }
               else if (jumped) {
                  count++;
                  lastWord += phraseCharArray[currentIndex];
                  jumped = false;
               }
               else {
                  lastWord += phraseCharArray[currentIndex];
                  jumped = false;
               }
            }
            count++;
         }
         return count;
      }

      private bool IsValidWord(string word)
      {
         return word.Length > 0 && word != "
\"\"" && word != " ";
      }

      public int FindCharIndex(char[] param, char itemToFind,int startIndex)
      {
         int position = -1;
         for (int index = startIndex; index < param.Length; index++) {
            if (param[index].Equals(itemToFind)) return index;
         }
         return position;
      }

      public string GetSubStringFromArray(char[] source, int startIndex, int endIndex)
      {
         string word = string.Empty;
         for (int index = startIndex; index < endIndex; index++) {
            word += source[index];
         }
         return word;
      }

      public char[] ConvertToCharArrayFrom(string phrase)
      {
         char[] characterBucket = new char[phrase.Length];
         int phraseLength = phrase.Length;

         for (int index = 0; index < phraseLength; index++) {
            characterBucket[index] = phrase[index];
         }

         return characterBucket;
      }

      public bool CompareChar(char targetChar, char compareToChar) {
         return targetChar == compareToChar;
      }

      public bool IsWhiteSpace(char compareToChar) {
         return CompareChar(CHAR_WhiteSpace, compareToChar);
      }

      public bool IsDoubleQuote(char compareToChar) {
         return CompareChar(CHAR_DoubleQuote, compareToChar);
      }

      public string Trim(string phrase) {
         string trimmed = string.Empty;
         if (phrase.Length != 0) {
            trimmed = LTrim(RTrim(phrase));
         }
         return trimmed;
      }

      public string LTrim(string phrase) {
         int indexOfValidChar = 0;

         char[] characterBucket = ConvertToCharArrayFrom(phrase);

         while (IsWhiteSpace(characterBucket[indexOfValidChar])) {
            indexOfValidChar++;
         }

         return GetSubStringFromArray(characterBucket, indexOfValidChar, phrase.Length);
      }

      public string RTrim(string phrase) {
         char[] characterBucket = ConvertToCharArrayFrom(phrase);

         int indexOfValidChar = characterBucket.Length - 1;

         while (IsWhiteSpace(characterBucket[indexOfValidChar])) {
            indexOfValidChar--;
         }

         return GetSubStringFromArray(characterBucket, 0, indexOfValidChar + 1);
      }
   }
}

Good mind exercise if you ask me.

Wednesday, January 03, 2007 12:47:36 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.NET
Archive
<January 2007>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Keith Rull
Sign In
Statistics
Total Posts: 260
This Year: 57
This Month: 0
This Week: 0
Comments: 116
Themes
Pick a theme:
Ads
All Content © 2008, Keith Rull
DasBlog theme 'Business' created by Christoph De Baene (delarou)