Sunday 21 July 2013

Determine if any anagram of a string can be a palindrome.

The Problem : 

      Given a string containing only lowercase alphabets, determine whether an anagram of this string can be a palindrome. Output YES if an anagram which is a palindrome exists and NO otherwise. The length of the string can vary between 1 and 100000, both inclusive.

Examples :

Input String : aab
Output : YES
Explanation : aba is an anagram which is a palindrome

Input String : babb
Output : NO
Explanation : No anagram of "babb" exist which is a palindrome

Input String : a
Output : YES
Explanation : a is itself a palindrome

Input String :bbabaaa
Output : YES
Explanation aabbbaa is an anagram which is a palindrome


The Solution : 

      A brute force way of solving this would be to generate all anagrams of the given string and then check whether any of them is a palindrome. But a string of length n (of distinct characters) can have n! different anagrams. Thus this method is not feasible even for small values of n (5!=120, 10!=3628800). A faster solution is thus needed.

      Lets look at an even length string. For this to be a palindrome the first half of the string must match the second half. So each characters in the first half of the string must also be present in the second half. Hence, there must be an even number of occurrences of each character in the string. (Note that here we say even occurrences of each character and not 2 occurrences. Why?. Consider the case where we have 4 occurrences of character 'a'. This means two of them can lie in the first half and the other two in the second half, hence an even number of occurrences is acceptable).

      Now lets take the case of an odd length string. Here the middle character of the string can be anything. Only the former part of the string (before the middle character) must match the latter part(after the middle character). So the middle character does not need a matching character, but the rest of the characters must occur in pairs (i.e. each character other than the middle must occur an even number of times in the string).

Now, for the problem at hand.

Case 1: Even length string 
   
      If each character of the string occurs an even number of times then we can make a palindrome out of it by rearranging the characters. For each character in the first half there shall exist a matching one in the second half. So we just need to count the occurrence of each character. If each character occurs an even number of times we can print YES.

Case 2: Odd length string

      Here, in a palindrome, all characters must have a matching pair except the middle one. So each character must occur an even number of times except one. So in a random string if all characters except one occur an even number of times, then these characters can be arranged in the first and second halves of the string. Now for the character that occurs an odd number of times. Suppose it occurs 5 times. Then 4 occurrences of this can be included in the first and second halves of the palindrome and the remaining one occurrence will become the middle character.
       Note that if, in a string, we had more than one character occurring an odd number of times the we could not have created a palindrome out of it.

So the logic becomes :

If string is of even length, check if all characters occur an even number of times, if they do print YES else print NO.

If string is of odd length, check if all but one characters occur an even number of times, one character must occur odd number of times, if these conditions satisfy print YES else print NO.


The Implementation:

      Here we need to count the occurrence of only 26 lowercase alphabets. So take an array of length 26. The count of 'a' will stored at the zeroth positions, 'b' at the first position and so on. Initialize this array with 0's. Lets call this array a[].

      Now a naive implementation would be to simply go through the string and increment the corresponding position in the array. At the end go through the array to check if the requirements defined in the logic are met. There is however a better solution where we need not traverse the array to get the solution.

      We take a flag variable to indicate the number of characters which occur odd number of times in the string. Every time we encounter a character we shall toggle the corresponding position in the array. Since the initial value of the position was 0, the first time it is toggled, it will become 1. On the next toggle it will become zero. Hence, a value 1 indicates the first occurrence and a value zero indicates the second occurrence. So every time a position becomes 1 increment the flag, and every time it becomes zero decrement the flag.

      So at any point during the traversal of the string the flag will indicate the number of characters whose occurrence count till this point is odd. Lets see this with an example.

Lets take the string ababb. A dry run is shown in the following table

Position   Character           array a[]                flag
   0               a           a[0]=1,others 0                   1    (till this point a-odd)
   1               b           a[1]=1,a[0]=1,others 0       2    (till this point a-odd, b-odd)
   2               a        a[0]=0,a[1]=1,others 0        1    (till this point b-odd)
   3               b a[1]=0,others 0                   0    (till this point none-odd)
   4               b a[1]=1,others 0                   1    (till this point b-odd)


The toggle can be implemented by using the XOR operator " ^ ".

Now to display the result, the following steps are followed :

1. Find length of string
2. If even then if flag=0 print YES esle print NO
3. If odd then if flag=1 print YES else print NO

The Code (in C): 

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
   int a[26],i,flag=0,len=0;
   char str[100001],*ptr=NULL;
   for(i=0;i<26;i++)
   a[i]&=0;
   scanf("%s",str);   //the input
   ptr=str;
   while(*ptr)   //traversing the string
   {
      len++;   //counting the length
      a[*ptr-97]^=1;   //toggle the position for if ptr points to a the a[*ptr-97] translates to a[0]
      if(a[*ptr-97])   //if position became 1
         flag++;
      else   //if position became 0
         flag--;
      ptr++;
   }
   if(len&1)   //if string is of odd length
   {
      if(flag==1)
         printf("YES");
      else
         printf("NO");
   }
   else   //if string is of even length

   {
      if(flag==0)
         printf("YES");
      else
         printf("NO");
   }
   return 0;
}

      Note that if in the problem it was not specified that the contents of the string are lowercase alphabets, then we could take the array to be of length 256 to take into account all the ASCII characters.

Saturday 20 July 2013

Capture Screenshot/Part of Java GUI

      In this post we shall see how to capture a screenshot with java. Also, we shall see how to capture the GUI (complete with the frame or partial e.g. a graph displayed in a panel) thrown by a Java Program. This may be useful in the case when we have to take a print out of, say, a graph or an image which is displayed on the Graphical User Interface(GUI).

Part 1 : The Screenshot

      To do this we shall make use of the Robot, BufferedImage and ImageIO classes. A brief description of how the classes are used follows :

Robot :  The Robot class has a function called createScreenCapture() which take as parameter a Rectangle object. The Rectangle object specifies the portion of the screen to capture (through coordinates). It returns a BufferedImage object. For taking a screenshot the rectangle must cover the entire screen. We can get the screen size by using the Toolkit.getDefaultToolkit().getScreenSize() method.

BufferedImage :  This class is used to describe an image. We shall store the return value from the call to the createScreenCapture() method of the Robot class in a BufferedImage object. Then this will be used to write a file containing the image using the ImageIO class.

ImageIO : It has a static method called write() which takes three parameters : the image(BufferedImage object), the format of the file to write(e.g. png) and the name of the file.


The CODE : 

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
class ScreenCapture {
   public static void main(String args[]) {
      try {
         Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
         BufferedImage capture = new Robot().createScreenCapture(screenRect);
         ImageIO.write(capture, "png", new File("d:\\screencapture.png"));
      }catch (Exception ex) {
         System.out.println(ex);
      }
   }
}


Part 2 : Cpturing Java GUI

      Now, we shall try to capture the GUI displayed by a Java Swing/AWT program. This can be useful when we have to print the whole layout displayed by a program or print a portion of it (say a graph or an image displayed on it). To do this we shall make use of the BufferedImage and the ImageIO classes. The following points explain the process :

1. Instantiate a BufferedImage object (called capture in our example) using the three argument contructor. The arguments passed are the a) width - width of the created image b) height - height of the created image c) imageType - type of the created image.
2. Call the components paint method(the component whose contents are to be captured). Pass as argument capture.getGraphics(). When the getGraphics() method is called on a component, it returns the component's graphics context, which lets you draw on a component. When this is passed as argument to paint method, the contents of the component calling the paint method(pnl2 in our case) are drawn on the object whose Graphic context is passed as argument.
3. Lastly we use the ImageIO.write() method to write the BufferedImage object to a file.


The CODE : 

Here we display a simple frame with two panels and capture the contents of pnl2 in an image.

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class CapturePanelInFrame extends JFrame {
   JPanel pnl1,pnl2;
   JLabel lab1,lab2;
   public CapturePanelInFrame() {   //Creating the GUI
      pnl1=new JPanel();
      pnl2=new JPanel();
      pnl1.setBackground(Color.blue);
      pnl2.setBackground(Color.green);
      lab1=new JLabel("This is the Label in Panel1");
      lab2=new JLabel("This is the Label in Panel2");
      pnl1.add(lab1);
      pnl2.add(lab2);
      setLayout(new GridLayout(2,1));
      add(pnl1);
      add(pnl2);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(400,200);
      setVisible(true);
      captureit(pnl2);
   }
   private void captureit(JComponent comp) {
      Rectangle rec = comp.getBounds(); // Getting the size of Component
      BufferedImage capture = new BufferedImage(rec.width, rec.height,BufferedImage.TYPE_INT_ARGB);
      comp.paint(capture.getGraphics());//capturing the components content in the capture object
      try {
         ImageIO.write(capture, "png", new File("capturepnl.png")); //writing the captued image to a file
      } catch (Exception e) {
         System.out.println(e);
      }
   }
   public static void main(String args[])
   {
      new CapturePanelInFrame();
   }
}


      Note that we pass the component to be captured to the captureit() method. So if we need to display the whole frame that is to be displayed, we can simply pass the JFrame object.

Saturday 6 July 2013

Open browser with proxy settings set from Java code

      In this post we aim to to write a java application which lets the user click a button to open a browser with its proxy settings set. To open an application from java we can use the exec method of the java Runtime class. So one can simply open a browser from java code. But the second part of the problem states that its proxy settings must be set to a specific value. In order to achieve this we shall make use of Google Chrome's switches. A detailed description of the entire process is given below.

Google Chrome Switches : 

      The Chrome Browser allows the use of command line flags (or "switches") that the browser accepts in order to enable particular features or modify otherwise default functionality. To use these switches we need to modify the target of an application. This can be done as follows.

Step 1 : Create a shortcut of the chrome.exe file. (To create a shortcut right click on the chrome.exe application, go to the Send To submenu and click on Desktop(create shortcut) item. This will create a shortcut of the application on your desktop).

Step 2 : Right click on the shortcut and click on Properties.

Step 3 : Append the following flag to the target text box value --proxy-server=127.0.0.1:8080. Here 127.0.0.1, 8080 are the IP and port of the proxy server (You may change these to reflect your own proxy server). With this flag the target must now look like chrome.exe --proxy-server=127.0.0.1:8080. Note that there is a space between chrome.exe and the flag.

Step 4 : Click on Apply and close the Properties window.

      Now  if you open the shortcut it will start the browser with its proxy setting set. Note that if an instance of the chrome browser is already opened then the proxy settings wont be used, so you must close any running instances of the browser before opening the shortcut. These proxy settings will not be shown in the proxy settings accessible through the settings tab of chrome. So in order to verify you can set the proxy to any random free ip-port address and open the shortcut. If the proxy settings were indeed set, opening any website in the browser will show you the following error : Unable to connect to the proxy server. (for this check you may use 127.0.0.1:8080 as proxy settings provided you do not have a proxy set up on your machine).

      So if we are able to somehow open this shortcut from our java code we are set. We shall do exactly this with the exec method of the  Runtime class.


The Runtime class :

      The Runtime Class in java encapsulates the runtime environment. You can get a reference to the current Runtime object by calling the Runtime.getRuntime() method. Once a reference to the current runtime object is obtained we can call the exec method to execute a specific command. This command must open the shortcut of the browser that we had created earlier. The following command accomplishes this  :

cmd /c start /d \"d:\" chrome.lnk

      Note that here d: is the path of where our application is and chrome.lnk is the name of the application.  This means that I had kept the shortcut in my d: drive. So you can change the path to reflect the location of your shortcut file. (The name is chrome .lnk because the shortcuts in windows have the extension lnk).


The CODE!

Following is the complete code that does the above :

public class OpenBrowser {
   public static void main(String[] args) {
      try {
         Process process = Runtime.getRuntime().exec("cmd /c start /d \"d:\" chrome.lnk");
      }
      catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}


Now the incorporation of the above method into an application where a click on a button triggers the above task is trivial.

Warning : Note that Google states the following on its chromium page
"It is important to note that using these switches is not supported or recommended. They should only be used for temporary cases and may break in the future."
So use this solution at your own risk :)
  

Saturday 1 June 2013

Capture packets in Java using JPCAP (Ping packets)

      Java does not provide any inbuilt libraries for capturing IP packets. Hence we must rely on third party libraries for this task. JPCAP is one such library. JPCAP is an open source library for capturing and sending network packets from Java applications. It provides facilities to :

1. capture raw packets live from the wire.
2. save captured packets to an offline file, and read captured packets from an offline file.
3. automatically identify packet types and generate corresponding Java objects (for Ethernet, IPv4, IPv6, ARP/RARP, TCP, UDP, and ICMPv4 packets).
4. filter the packets according to user-specified rules before dispatching them to the application.
5. send raw packets to the network

      JPCAP makes use of native libraries for capturing packets. For Windows it uses WinPcap and for UNIX it relies on libpcap. As an example we shall capture the ping messages received by our machine. A small description of Ping is given below. 

Ping


      Ping is used to test the reachability of a host on an Internet Protocol (IP) network. It operates by sending Internet Control Message Protocol (ICMP) echo request packets to the target host and waiting for an ICMP echo reply messages. In the process it measures the time from transmission to reception (round-trip time) and records any packet loss.


Downloading dependencies & Setting up the environment



Downloads :


      Since JPCAP relies on WinPcap(for Windows)/libpcap(for UNIX), we must first download and install them. For Windows, WinPcap can be downloaded from the site http://www.winpcap.org. This must now be installed on your system. Also we need the JPCAP library, which can be downloaded from the link http://sourceforge.net/projects/jpcap/. If the links dont work simply search for them on google and choose the first links suggested.

Setup :


      For JPCAP to work you need to do the following two things :

1. Add jpcap.dll to the Java bin folder. The following steps accomplish this :
a.) Extract the downloaded JPCAP folder.
b.) Navigate to the lib folder inside the extracted folder. (i.e. navigate to jpcap-0.01.16-win32\lib. Note that the name of the downloaded folder may be different for a different version. It will however be of the form jpcap-...-win32). The lib folder must contain the jpcap.dll file.
c.) Copy the jpcap.dll file.
d.) Paste it in your jdk's bin folder. (Navigate to your Java folder. Open the jdk folder. Open the bin folder. Paste the file here)

2. Add the jpcap jar file to your classpath. The jpcap jar file is the file net.sourceforge.jpcap-0.01.16 included in the jars folder of the downloaded JPCAP folder. (If you are using Eclipse, you can do this by right clicking on the project, selecting Build Path, selecting add external archives and adding the required jar file).

The CODE!



PART 1 : To capture any packets we must use one of the network interfaces of our machine. To get the id of the network interface we use the following short java program.(Alternatively you can type ipconfig in the command prompt to get the device ID)

import net.sourceforge.jpcap.capture.CaptureDeviceNotFoundException;
import net.sourceforge.jpcap.capture.PacketCapture;
public class GetDeviceID {
    public static void main(String args[]){
        try {
           PacketCapture capture = new PacketCapture();
           String device=capture.findDevice();
           System.out.println(device);
        } catch (CaptureDeviceNotFoundException e) {
           // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

The above programs displays something like :

\Device\NPF_{04FGHGHA-D453-4450-945E-1145454557B4}
  Microsoft

Note down the part from the start of the string to the closing brace. This is the interface that we will listen to for packets.

PART 2 : Now we can capture the packets using the code given below.
The device ID being used is the one we found above. So replace the one shown below with your own. Note how the Device ID is specified in the call to capture.open().


import net.sourceforge.jpcap.capture.CaptureDeviceLookupException;
import net.sourceforge.jpcap.capture.PacketCapture;
import net.sourceforge.jpcap.capture.PacketListener;
import net.sourceforge.jpcap.net.ICMPMessages;
import net.sourceforge.jpcap.net.ICMPPacket;
import net.sourceforge.jpcap.net.Packet;

public class PingCapture {
    public static void main(String[] args) throws CaptureDeviceLookupException {
        Capture cap = new Capture();
        cap.doCapture();
    }
}

class PingListener implements PacketListener {
    @Override
    public void packetArrived(Packet packet) {
        try {
            // only ICMP packages
            if (packet instanceof ICMPPacket) {
                ICMPPacket tcpPacket = (ICMPPacket) packet;
                int data = tcpPacket.getMessageCode();
                // only echo request packages
                if (data == ICMPMessages.ECHO) {
                    // print source and destination.
                    String srcHost = tcpPacket.getSourceAddress();
                    String dstHost = tcpPacket.getDestinationAddress();
                    System.out.println("Ping from: " + srcHost + " to " + dstHost);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Capture {
    public void doCapture() {
        // create capture instance
        PacketCapture capture = new PacketCapture();
        // add listener that handles incoming and outgoing packages
        PingListener pingListener = new PingListener();
        capture.addPacketListener(pingListener);
        try {
            capture.open("\\Device\\NPF_{04FGHGHA-D453-4450-945E-1145454557B4}", true); // Replace the device ID with your own
            while (true) {
                capture.capture(1); // capture one packet, since this is in a loop, it will keep on capturing more packets
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            capture.removePacketListener(pingListener);
            capture.endCapture();
            capture.close();
        }
    }
}


      If everything went correctly, you will be able to see any ping requests received by you machine. If no ping messages are coming then nothing will be displayed. In this case to make sure whether the code is working, add a System.out.println() as the first statement of the packetArrived method. This will verify whether any packets are being received.

      Some common errors that may come up when you try to run the above code  are listed below:

Error 1: 
PacketCapture: loading native library jpcap.. Exception in thread "main" java.lang.UnsatisfiedLinkError: no jpcap in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
Solution: jpcap.dll file has not been copied to the java bin folder. See point #1 in the setup above to rectify this.


Error 2:
net.sourceforge.jpcap.capture.CaptureDeviceOpenException: Error opening adapter: The system cannot find the device specified. (20)
at net.sourceforge.jpcap.capture.PacketCapture.open(Native Method)
Solution: The device name is not correct. Replace the device specified in the above code to you own device ID. Note how the ID is specified(with two backslashes).


Error 3:
Getting errors during compilation of the form
error: package net.sourceforge.jpcap.capture does not exist
import net.sourceforge.jpcap.capture.CaptureDeviceLookupException;
Solution: Add the jpcap jar file to classpath. See point #2 in the setup above to rectify this.

Monday 27 May 2013

Expandable Treeview in HTML (without images).

      A treeview presents a hierarchical view of information. Each item can have a number of subitems. An item can be expanded to reveal the subitems, and collapsed to hide them. The following figure gives an idea of what it actually looks like :



      This kind of a treeview can be used in HTML reports to hierarchically categorize information in the way shown above. Most solutions for this, however, use external images for the plus/minus icons. This may not acceptable if the report has to be portable (as it would require that the icon file also be sent with the HTML report). So here we generate the above tree-view without using any extra image files, with the help of plain HTML elements, JavaScript and CSS.

      The source code of the HTML document containing the treeview is shown below. An explanation of how this was achieved follows.


<html>
 <head>
  <style>
   .invisible
   {
    background-color: #E6E6E6;
    border: none;
    padding-bottom: 5;
   }
   li,ul
   {
    list-style-type: none;
   }
  </style>
  <script type="text/javascript">
   function toggle(id,v){
    if(v.value=="+")
     v.value="-";
    else
     v.value="+";
    var e=document.getElementById(id);
    if(e.style.display=='')
     e.style.display='none';
    else
     e.style.display='';
   }
  </script>
 </head>
 <body>
  <ul>
   <li><!- (+ item)->
    <input id="item1" class="invisible" type="button" onclick="toggle('content1',this)" value="+" style="width:20px;height:20px;"/>
    <label for"item1"> item 1 (nested item)</label>
    <div id="content1" style="display:none">
    <ul>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.1</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.2</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.3</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.4</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.5</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.6</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.7</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 1.8</li>
    </ul>
    </div>
   </li>
   <li><!- (normal item) ->
         
    item 2 (nomal item)
    
   </li>
   <li><!- (+ item)->
    <input id="item3" class="invisible" type="button" onclick="toggle('content3',this)" value="+" style="width:20px;height:20px;"/>
    <label for"item3"> item 3</label>
    <div id="content3" style="display:none">
    <ul>
     <li>     item 3.1</li>
     <li>
      <input id="item3.2" class="invisible" type="button" onclick="toggle('content3.2',this)" value="+" style="width:20px;height:20px;"/>
      <label for"item3.2">item 3.2</label>
      <div id="content3.2" style="display:none">
      <ul>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.2.1</li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.2.2</li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.2.3</li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.2.4</li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.2.5</li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.2.6</li> 
      </ul>
     </li>
     <li>
      <input id="item3.3" class="invisible" type="button" onclick="toggle('content3.3',this)" value="+" style="width:20px;height:20px;"/>
      <label for"item3.3">item 3.3</label>
      <div id="content3.3" style="display:none">
      <ul>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3.1</li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3.2</li>
       <li>
        <input id="item3.3.3" class="invisible" type="button" onclick="toggle('content3.3.3',this)" value="+" style="width:20px;height:20px;"/>
        <label for"item3.3.3">item 3.3.3</label>
        <div id="content3.3.3" style="display:none">
        <ul>
         <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3.3.1</li>
         <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3.3.2</li>
         <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3.3.3</li> 
        </ul>
       </li>
       <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3.6</li> 
      </ul>
     </li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 3.3</li>
    </div>
   </li>
   <li><!- (+ item)->
    <input id="item4" class="invisible" type="button" onclick="toggle('content4',this)" value="+" style="width:20px;height:20px;"/>
    <label for"item4"> item 4</label>
    <div id="content4" style="display:none">
    <ul>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 4.1</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 4.2</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 4.3</li>
     <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item 4.4</li>
    </ul>
    </div>
   </li>
  </ul>
 </body>
</html>

Explanation :

The List :
We can visualize each subtree as a separate list. We can thus use the HTML list <ul> to display the subtree. This <ul> will contain all the items in this subtree as list iems <li>. If any of the list items itself is a subtree we can include another <ul> inside the <li> elements. To hide the bullets that accompany the list we use the CSS property "list-style-type: none".

The Icons :
For the expandable icon, since we cannot use external image file for the icons, we shall make use of HTML elements. We use a Button in this case. For making it look less like a button and more like an expandable icon, we remove the border and change the background color of the button. We also set the text of the button to a '+' to make it look like an expandable icon. On clicking the button the text will change to '-' and the subtree will become visible.

The hidden <div> tags : 
To display/hide the subtree we can use div tags with their style set to "display:none". On clicking the '+' icon we shall change this style attribute to the default(i.e. empty), which will make it visible once again.

The Javascript :
We shall use Javascript to hide/display the subtree. The following javascript function will take care of this. The function takes two arguments, the contained div tag and the button itself. In the function we check the text of the button from a '+' to a '-' for expanding and vice-versa for hiding the contents. Also we change the style attribute of the div tags from 'none' to empty (i.e. ' ') and for making it visible or vice-versa for hiding it.


function toggle(id,v){
    if(v.value=="+")
        v.value="-";
    else
        v.value="+";
    var e=document.getElementById(id);
    if(e.style.display=='')
        e.style.display='none';
    else
 e.style.display='';
}

Friday 3 May 2013

The Power of Recursion


               “To iterate is human, to recurse divine”. Recursion is indeed a powerful technique capable of simplifying various complex programming tasks. Perhaps one of the best known examples of this is the Towers of Hanoi Problem. In short the problem consists of three towers and disks of various sizes. These disks are stacked on one tower (smallest on top) and are to be moved to another tower using the third tower as auxiliary. Two rules that must be observed are a) only the top disk can be moved from any tower at a time and b) a larger disk cannot be placed on top of a smaller one. The task of writing an algorithm that will get us the set of moves that must be performed for moving n disks in the way defined above is not an easy one. However using recursion it can be hugely simplified. But before writing a recursive solution to the problem lets delve further into what recursion is and how it can be used to solve simpler problems.

               Recursion is the process of defining a problem in terms of itself. To understand this, consider the following situation. Suppose we need to find the factorial of a number say 3. Now 3! can be written as 3! = 3 X 2!. In general we can write n! as n! = n X (n-1)!. So we have represented the problem in terms of itself. Thus if we can compute (n-1)! then we can also find n! with just a single multiplication. Also we must consider a base case. This base case is where the problem must terminate. For the factorial example the base case would be 0! which is equal to 1. 0! factorial is chosen as the base case because this is the least number whose factorial can be calculated. Now, for the implementation part, we can make use of a function which calls itself (recursion). Note that since here we have a function that solves a problem by calling itself, we have in fact represented the problem in terms of itself i.e. we have represented the problem as:

                factorial(n)=n * factorial(n-1) .

A recursive function (function that calls itself) to accomplish the above task is shown below :

int factorial(int n){
     if(n==0) return 1;//The base case
     else return n*factorial(n-1);//The recursion
}

The following figure explains the working : 



               Each box represents a call to a function and the first line in each box shows the value with which it is called. Each call to the function will return a value indicated by the number beside the red arrow. The rest is self-explanatory.

               So, we were able to write a recursive solution to the factorial problem once we had figured out two crucial things

     1. The base case: the case where the recursion will terminate. (n = 0 in the above case).
     2. How the function represented in terms of itself. (factorial ( n ) = n * factorial (n -1 ) ).

               The above technique can be used to approach a recursive problem. Now consider another problem, finding the nth Fibonacci number. Fibonacci numbers start with 0 , 1 , . . . and each successive no is the sum of the previous two. The Fibonacci series thus goes like 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 . . . and so on. So for finding the nth Fibonacci number we can just sum the previous two. We can represent this as fib(n) = fib(n-1) + fib(n-2), where fib(int n) is a function that finds the nth Fibonacci number. Here the first two numbers remain constant so they constitute the base cases which are Fib(1)=0 & Fib(2)=1, representing the fact that the first Fibonacci number is 0 and the second Fibonacci number is 1. A recusive function for this can be written as :

int fib(int n){
     if(n==1) return 0 ; //Base case #1         
     else if(n==2) return 1 ; //Base case #2
     else return fib(n-1) + fib(n-2) ; // The recursion 
}


               Note that in both of the above problems we were never concerned with the actual theme of the problem (finding factorial of a number or finding the nth Fibonacci number). We assumed that a function would do that for us and just represented the problem in terms of itself and wrote a straightforward algorithm for it. The rest recursion did for us automatically. Such is the power of recursion.
               
               So to sum up, the idea behind recursion is that a problem can be solved by breaking it up into smaller pieces, solving each of those smaller pieces by breaking them up into even smaller pieces and so on till we reach a piece that can be solved non trivially(the base case).
               
               For the above two cases simpler iterative solutions are possible and perhaps more efficeitn, but for certain complex problems it is easier to write a recursive solution than an iterative one. The Towers of Hanoi problem illustrates this fact.

               Let us first state the Towers of Hanoi problem formally:  
                
               The problem consists of three pegs/towers and a number of disks of varying sizes which can be slid onto any peg/tower. Each disk is of a different size. Initially the disks are stacked on one of the towers (lets call it A) one atop another with the smallest one at the top. The goal is to move all disks from tower A to another tower (lets call this C), using the third tower (B) as auxiliary while obeying the following rules:
1. Only the top disk can be moved from a tower at any time.
2.  No disk must be placed on top of a smaller disk.

Let us consider a recursive strategy for moving n disks.
Step 1 :  Move n-1 disks from Tower A to Tower B
Step 2 :  Move 1 disk from Tower A to Tower C
Step 3 : Move n-1 disks from Tower B to Tower C

               This would solve the problem. (Note that here we are not concerned with how we would move the n-1 disks. The steps are shown visually in the figures below :



               The base case here would be that of a single disk which we can move directly from Tower A to Tower C. The towers are named A, B, C where B is the auxiliary tower. The recursive solution is shown below :

public void move( int numberofdisks, char firstTower, char auxTower, char finalTower )
{
     if(numberofdisks == 1){
          System.out.println("Move disk from "+firstTower+" to "+finalTower);  //#0
     }
     else{
          move(numberofdisks-1,firstTower,finalTower,auxTower);   //#1
          System.out.println("Move disk from "+firstTower+" to "+finalTower);  //#2
          move(numberofdisks-1,auxTower,firstTower,finalTower);  //#3
     }
} 

Explanation :

#0 : This illustrates the base case where a single disk can be moved from the first to the final tower directly.

#1 : This is Step 1 of the solution. Here we move n-1 disks from firstTower to auxTower using the finalTower as auxiliary. Note that in the function prototype auxiliary tower is denoted as the third parameter (first is the no. of disks), so here we had to use finalTower as auxiliary(third parameter) in the actual function call.

#2 : This is Step 2 of the solution.

#3 : This is Step 3 of the solution. Here we move n-1 disks from auxTower to finalTower using firstTower the as auxiliary. So here we had to use firstTower as auxiliary(third parameter) in the actual function call.

             For 3 disks the above program the function call move(3, ‘A’, ’B’, ’C’) displays the following steps :

Move disk from A to C
Move disk from A to B
Move disk from C to B
Move disk from A to C
Move disk from B to A
Move disk from B to C
Move disk from A to C

               “Move disk” obviously means moving the top disk from the tower.

               This above solution clearly demonstrates how easily recursion can be used to solve such complex problems. The use of recursion in an algorithm, however, has both advantages and disadvantages. The main advantage is usually simplicity. (for solving certain problems like the Towers of Hanoi, preorder/inorder/postorder traversal of binary trees etc.). Also some problems like displaying a list of all files of the system cannot be solved without recursion. The main disadvantage is often that the algorithm may require large amounts of memory if the depth of the recursion is very large.

               Recursive techniques are also widely used to implement important algorithms based on the Divide & Conquer approach like quicksort and merge sort as well as graph based algorithms like Depth First Search.