Sunday, September 12, 2010

Karate Chop - An Imperative and Functional implementation

Karate Chop is a Kata about implementing binary search five different ways. I could come up with 2 obvious ways - an imperative style with iteration and a functional style based on the solution inspired by this site . So here goes:

Imperative:

package org.bk.karatechop

class KarateChop {
 def chop(aNumber:Int, anArray:Array[Int]):Int = {
  var minIndex=0
  var maxIndex = anArray.length-1
  while(minIndex<=maxIndex){
   var midIndex = (minIndex+maxIndex)/2
   var atMidIndex = anArray(midIndex)
   if (aNumber>atMidIndex){
    minIndex=midIndex+1
   }else if(aNumber<atMidIndex){
    maxIndex=midIndex-1
   }else{
    return midIndex
   }
  }
  
  -1
  
 }
}
Functional: 
package org.bk.karatechop

class KarateChopRecursive {
 def chop(aNumber:Int, anArray:Array[Int]):Int = {
  
  def recurse(low:Int, high:Int):Option[Int] = { 
   (low + high)/2 match {
    case _ if high < low => None
    case mid if aNumber < anArray(mid)  => recurse(low, mid - 1)
    case mid if aNumber > anArray(mid)  => recurse(mid + 1, high)
    case mid => Some(mid)
   }   
  }
  
  recurse(0,anArray.length-1).getOrElse(-1)
  
  
 }
}

Tuesday, September 7, 2010

Perfect Number implementation using Scala Actor, Spring Integration, Java Executors, Kilim based Actor

A Simple non-threaded (and non-optimized) java implementation for figuring out if a number is a perfect number is the following:

public class SimplePerfectNumberUtil implements PerfectNumberUtil{

 @Override
 public boolean isPerfect(int aNumber) {
  return sumOfFactors(aNumber)==2*aNumber;
    }
 
 private int sumOfFactors(int aNumber){
  int sum = 0;
  for (int i=1;i<=aNumber;i++){
   if (aNumber%i==0){
    sum+=i;
   }
  }
  
  return sum;
 }

}



Programming Scala book provides a sample scala actor implementation for this by breaking up the task of determining whether a large number is a perfect number by breaking up the large number into a range of smaller numbers - eg. a number like 3000 can be split up into say 0-1000, 1001-2000, 2001-3000, with a task responsible for summing up the factors in each of these ranges and summing up the result.

A slightly modified implementation based on the Programming Scala book is the following:

class PerfectUtilScala {

  def isPerfect(candidate: Int) = {
    val RANGE = 10000000
    val numberOfPartitions = (candidate.toDouble / RANGE).ceil.toInt
    val caller = self
    
    
    val sumoffactorsActor = actor{
     loop {
      react {
    case msg:FactorsRangeForCandidate =>
     caller ! sumOfFactorsInRange(msg.lower, msg.upper, msg.candidate)
   }  
  } 
    }


    for (i <- 0 until numberOfPartitions) {
      val lower = i * RANGE + 1;
      val upper = candidate min (i + 1) * RANGE
      
      sumoffactorsActor ! new FactorsRangeForCandidate(lower, upper, candidate)
    }

    val sum = (0 /: (0 until numberOfPartitions)) { (partialSum, i) =>
      receive {
        case sumInRange: Int => partialSum + sumInRange
      }
    }

    2 * candidate == sum
  }

  private def sumOfFactorsInRange(lower: Int, upper: Int, number: Int) = {
    (0 /: (lower to upper)) { (sum, i) => if (number % i == 0) sum + i else sum }
  }

}


class FactorsRangeForCandidate(val lower:Int, val upper:Int, val candidate:Int)

A Java Executors based implementation is the following:
public class ThreadPoolPerfectNumberUtil implements PerfectNumberUtil{ 
 private ExecutorService threadpool = Executors.newFixedThreadPool(3);
 @SuppressWarnings("unchecked")
    public boolean isPerfect(int aNumber) {
     int RANGE = Constants.RANGE;
     int numberOfPartitions = new Double(Math.ceil(aNumber * 1.0 / RANGE)).intValue();
     Future[] sumOfFactors = new Future[numberOfPartitions];
     
     for (int i=0;i{

 private final int lower;
 private final int upper;
 private final int anumber;
 
 
 public SumOfFactorsTask(int lower, int upper, int anumber){
  this.lower = lower;
  this.upper = upper;
  this.anumber = anumber;
 }
 
 
 @Override
    public Integer call() {
  int sum=0;
  for (int i=lower;i<=upper;i++){
   if (anumber%i==0){
    sum+=i;
   }
  }  
  
  return sum;
    }

}
And a Kilim based actor implementation:

public class ActorsPerfectNumberUtil extends Task implements PerfectNumberUtil {

 private Mailbox mailbox;
 private Mailbox resultmailbox;
 private SumOfFactorsActor sumOfFactors;

 public ActorsPerfectNumberUtil() {
  mailbox = new Mailbox();
  resultmailbox = new Mailbox();
  sumOfFactors = new SumOfFactorsActor(mailbox, resultmailbox);
  sumOfFactors.start();

 }

 public boolean isPerfect(int aNumber) {
  int RANGE = Constants.RANGE;
  int numberOfPartitions = new Double(Math.ceil(aNumber * 1.0 / RANGE)).intValue();

  for (int i = 0; i < numberOfPartitions; i++) {
   int lower = i * RANGE + 1;
   int upper = (i + 1) * RANGE;
   if (aNumber < upper)
    upper = aNumber;
   mailbox.putnb(new FactorsRange(lower, upper, aNumber));
  }

  int sum = 0;
  for (int i = 0; i < numberOfPartitions; i++) {
    sum += resultmailbox.getb();
  }

  if (sum == 2*aNumber)
   return true;

  return false;
 }
}
The codebase along with the Spring Integration based implementation is available at this Git location:
git://github.com/bijukunjummen/Perfect-Number.git

Saturday, January 30, 2010

Windows 7 and Ubuntu - My perspective

A screenshot of my desktop under Ubuntu:




and, a screenshot of the similar set of applications in Windows 7:




A constant battle that plays out everyday in my mind - to use Ubuntu or Windows as my primary development box
I use both interchangeably in my dual boot laptop, most of my work related files is kept in a shared partition, this way I can use either Ubuntu or Windows any time. I could use a virtual machine hosting Windows or Ubuntu but I don't like the idea of allocating a good chunk of resources to run a Virtual machine in my "not a high end" laptop.


I will continue to use both for the foreseeable future, the following is just an attempt to list down the specific reasons why I like/hate Ubuntu and Windows and prevents me from sticking to one or the other:




What do I really love about Ubuntu:
  1. The super clean desktop, once I have changed the default Ubuntu look by adjusting the DPI settings using this article(https://wiki.ubuntu.com/X/Troubleshooting/HugeFonts) and changed the theme to Murrina Gilouche(http://gnome-look.org/content/show.php/MurrinaGilouche?content=44510)
  2. Terminal - For controlling the small scripts that I have  - to start subversion, confluence, bamboo, run maven scripts
  3. Package Management tools - Synaptic, aptitude and apt-get make software install a cinch.


What do I really hate about Ubuntu:
  1. Lack of a good pdf reader plugin support in Google Chrome/Firefox.  I know Adobe provides a pdf reader for Linux but it does not work well with Google Chrome/Firefox
  2. Lack of ITunes port for Linux. Yes there is Rhythmbox, but it does not for some reason synch my iPod Nano.
  3. Picasa - I know a port using Wine is available, but I would have preferred a native version.
  4. Flash experience is buggy - It works but there are bugs - for eg, I have issues in watching videos in full screen mode at TED, if I go into a fullscreen mode there are times when I hear the sound but no window.
  5. Java applications like Netbeans, JEdit with default look and feel(typically Metal) look very bad in Ubuntu, if the L&F is changed to GTK then it is passable.
  6. Hibernate and Resume is very slow(order of minutes) in Ubuntu.


What do I really love about Windows:
  1. Default Windows Aero based desktop is very clean and I like the new taskbar in Windows 7
  2. Flash, Pdf Reader(and plugin!), Itunes, Picasa work well on Windows
  3. Office suite - some of my work related documents does not open up correctly using Open office, and there is no equivalent of Visio in Open office.
  4. Very fast Hibernate and Resume


What do I really hate about Windows:
  1. The command shell and Powershell are not as good and intuitive as the Linux terminal(tab completion, color support etc). Yes there is Cygwin, but I do have problems in some applications related to the different way paths are handled(forward vs backward slash and the default "Program Files" space resolution)