Google Search ...

Google
 

Wednesday, October 14, 2009

CodeBits ... Hoping it to be awesome :D

It happened that I applied for codebits and got selected :D
A few things about it (scraped from the website):
"3 days. 24 hours a day. 600 attendees. Talks. Workshops. Lots of food and beverages. 24 hour programming/hacking competition. Quizz Show. Rock Band Contest. Lots of gaming consoles. More food. More beverages. More coding. Sleeping areas. More fun. An unforgettable experience.

Oh, did we mention attendance is free? You need only to register and get approved for the event."

from the looks of it, it should be MAJOR fun ...
(esp the programming contest :) )

Wednesday, May 13, 2009

Getting Started ... GSOC

Started coding for GSOC a few days back. Though progress is really slow, Due to my exams till 1st June, Yet I've planned to catch up as per my schedule. Follow my wiki http://wiki.eclipse.org/A_Online_Judge/Assignment_Grading_System_for_IDE4EDU .. for updates and follow ups.

Phase 1 of the project is decided. And I'm yet to decide what I'm gonna do for Phase 2, after discussing it with my mentor. The updates will be put up on the timeline in the wiki. Hopefully the code should be accepted by the Eclipse community for the JavaLite environment of the project IDE4EDU. I might be using few ECF's API for the project too , the service discovery APIs look promising, so does the file transfer API. But first things first ... Let the 1st phase be completed :D

Update: Initial code has been committed. Check out the sources in the SVN Repo @ http://code.google.com/p/au4ide4edu

comments always welcome.. :)

Sunday, April 26, 2009

Google Summer of Code...

Yay !! Finally .. I've got accepted for Gsoc (Google Summer of Code 09) ! Sorry that I'm blogging this late. Anyhow I'll skip the details and would want you to check the site (Click here) for yourself.

I've been accepted for my proposal on Assignment Grading and Workflow Mechanism for Eclipse Org. Lucky indeed to work for Eclipse! My mentor is an awesome intellectual man too : Wayne Beaton. Apparently a bit of googling revealed that he is the "Evangelist" of Eclipse. That made me even more happier :D yay! I'd be getting $4500 as a stipend *if* I complete the project successfully. 1000 proposals were accepted this year and 101 where from India, making it the second highest after US.

Whats more cooler that I'd be getting a Certificate from Google , at the end of the program and guess what more.. A brand new Google T-shirt ;) !! I'd be soon documenting the details of my project on a wiki (and will update it here too).

So keep checking back... For more details and news about Gsoc.
Adios ..

Wednesday, March 25, 2009

Xtreme Programming !

“Write a c++ program to calculate a^b using functions (5 marks)” : this type of question appear frequently in our programming question papers. If you find even this particular question difficult to program , then I strongly recommend flipping pages right away and start looking for some other article. If not, you might very well get introduced to some very powerful programming techniques and optimizations. Noobs who want to get started (or has recently started) taking part in Online coding matches (Local, National or International.) should read this article.

What I mean about optimization technique is simply the method how you can make the running time of your program faster ! Damn right ... its not easy as it sounds ! Few types of optimizations which I feel every coder must be aware of:
1)I/O optimizations
2)Algorithmic Optimizations
3)Bit level Optimizations or Low Level Optimizations (Bit Masking)
4)Misc Optimizations (Ad Hoc types)

I'd like to explain some of these with a very simple and original problem:
Statement: “Given a string of numbers 'i' ; 0<=i<=60 ; Find the number of occurrences of each number. The output should be of format [ number: frequency] , sorted and separated by a whitespace. The size of the sequence is less than 10^6”
Example Test cases:
Input:
1 0 1 1 1 0 2 2 50 50 7 3
Output:
0:2 1:4 2:2 3:1 7:1 50:2

Right, now lets analyze ! The solution to this problem is very very simple indeed. But every problem in programming matches have a definite time limit.
The first step to solving any problem is to look at the input size. Sometimes the input size is over around 10^100 (of course they can give such sizes!). Optimizing I/O in such cases will save you a lot of time. I/O is very language specific. You should know your preferred programming language very well to accomplish this optimization. In case if you are using c++ , as a rule of thumb, “scanf() and printf()” are faster than “cin and cout”. The reason lies in the core implementation of the c++ I/O library. If you like to use java, reading raw inputs (with System.in()) is much faster than any buffered reader. Also avoid frequent parsing of data types as much as possible. An input size of 10^100 definitely needs an I/O optimization if you need to squeeze your code to fit the time constraint. 64 bit data types ( “long long” in c/c++ and “long double” in java) are slower than the 32 bit counterparts.

Now we will come to the “real” coding part ! A nice algorithm is all you need to make your program fit in the time limit. Anyone with a decent knowledge in programming will first think of a O(n^2) logic. In this he/she will first take a number (starting from the first) and then check for the repetitions till the end. Sadly the person also has to check for the numbers for which the frequencies has already been computed, and carefully skip them. This is an additional overhead, and some additional array has to be maintained to do the checking (memory overhead too). This algorithm can further be optimized by sorting the whole sequence first and then checking for repetitions. The code structure is fairly simple:

// let my input array be a[] and size be “len”
sort(a, a+len); // sorting the array
int count=1;
for(int i=1;i < len;i++)
{ if(a[i]==a[i-1]) count++;
else
{ printf(“%d:%d ”,a[i-1],count);
count=1; //resetting counter}
if(i==len-1) //taking care of the last case
printf("%d:%d ",a[i],count);
}

If you think a little, you will realize that theoretically it is slower than the previous approach. How?
Sorting time= N*logN
Worst case time: M* N*logN; (where M is the maximum repetitions of a sequence)
but fortunately the size if M normally is very less when compared to N ; hence this algo gives a decent running time overall. But its still not the best algorithm ! You can pull off a linear time algorithm too. The idea is very simple. Since 0<= i <=60 ; you can maintain a separate array, fill all numbers from 0 to 60 and check for its repetitions in a linear sweep of the main sequence. The easiest way to do this is with c++ stl maps. Sadly STL in c++ would have been either deleted or skipped for exam :P . I'll give you the code structure , learning STL (Standard Template Library) is your part.

std::map num;
int x;
for(int i=0;i < 60;i++)
num[i]=0;
while(scanf(“%d ”,&x)) //get the input until EOF
num[x]++;
for(int i=0;i < 60;i++)
{if(num[i]!=0)
printf(“%d:%d ”,i,num[i]);}

Thats it! These algorithms were a part a Ad Hoc optimizations actually. Some of other optimizations (Algorithm Based) would include:
1)Dynamic Programming (Memoization included in this case)
2)Optimizations in Graph Problems (Mainly involves optimizations of Data Structures)
3)Search Techniques (such as BST's, DFS, BFS)
4)Mathematical Optimizations (such as simple sieves, FFT, Modular exponentiation etc)

I'll now come to the last type of a beautiful and elegant optimization technique. As you all know everything in the computer is Bit oriented. Therefore if we can somehow manage to work and implement our algorithms at bit level, it would turn out much faster than the high level ones. Lets take an classical example:
Statement: Given a set s={i1,i2,...in}. Find the sum of every subset in its power set.
So how are you gonna solve it? “Bit masking” is a type of Bit Level Optimization and proves to be very easy to code in this case. We will solve this problem using brute force method for now (Other optimizations are also definitely possible). Classical “Knapsack” type of problems can be easily solved too.
At first we will denote the “choosing” of a number with 1 and “not choosing” with 0. Hence if one of my set is 2,3,4,8,7 and I want to pick 4 and 8 only; I would denote my “masked”value as 00110. Also note that (00110)2 =(6)10 Hence I have reduced the need of having an array of 5 ints (because we have 5 numbers in the set) and condensed them into one int ! Also notice the fact that the binary sequence ( 00000 to 11111 for this case ) will give all the possible permutations of the subsets in its power set. Confused ? Lets work with a very small example:
Let the set be : {4,7}
Hence power set : { phi, {4}, {7,}, {4,7}};
Since n=2;
its binary sequence:
0 0 ---> no items are picked
0 1 ---> Only 7 is picked
1 0 ---> Only 4 is picked
1 1 ----> both 4 and 7 are picked
Now the question is .. “How to play with the bits?”. Remember < < and > > operators ? If not, lemme just rush : < < is left shift and > > is right shift operator. a < < b will shift 'a' by 'b' bits to the left, filling zeros in the void. a > > b will shift 'a' by 'b' bits to the right. '&' and “|' are bitwise 'And' and 'Or' respectively. Note, a < < b is same as multiplying the number 'a' by 2^b and a > > b is same as dividing the number 'a' by 2^b. Work out manually to understand :)
Now there are a lot of formulas for bit manipulation. But for this we would just need to find out if 'i'th bit in the sequence is 1. If true we can pick it up and add it to our sum (Right?).
The formula : (x&(1 < < i)!=0) will tell you if your 'i'th bit in the set x is 1. (Very obvious once you work it out.) Now it all boils down to one logic: Iterate 'i' from 0 to 2^n and check for j'th bit being 1. If true add it to the sum and display it for the specific set. Increment 'i' in each step to go to the next subset in the powerset. The resulting code is extremely simple:
void calculate_sum ( int a[], int len)
{
int results[1 < < len]; /* declaring an array of size 2^len to hold results */
memset(results,0,sizeof(results)); /* jus initializing each array element to 0 */

// Break your head on this and I'm sure you will get it within hours ;)
for(int i=0;i< (1 < < len);i++)
{ for(int j=0;j < len;j++)
{if( i&(1 < < j) !=0) results[i]+=a[j]; }
}
for(int i=0;i<(1 < < len);i++)
cout < < “Sum of subset ” < < i < < “ = ” < < results[i] < < endl; /*display sum*/
}

Well those where few of the optimization techniques which are mostly used in any coding competition. Remember to do your homework well and learn proper algorithms first and then go for such optimizations. The rest I leave to you ...

Friday, March 28, 2008

TSP NN Heuristics

Wrote this piece of code in a hurry , for the Travelling Salesman Problem ...
NN Heuristics ... check it out..
wat dya think ?
Quality is bad ... but gud 4 express codin i guess .. ;)

#include < iostream >

using namespace std;

int main(void)
{

long g[100][100],n;
cout < < "Number of cities: " ;
cin > > n;
int i=0,j=0;

/* input the respective distances between the cities: */

for(i=0;i < n;i++)
{for(j=0;j < n;j++)
{
if(i==j)
{g[i][j]=0;continue;}

cout < < "Distance of City " < < i+1 < < " and " < < j+1 < < " = ";
cin > > g[i][j];
}
cout < < endl;
}

/* Creating a Symmetric matrix */

cout < < "Symmetric Matrix Generated is:" < < endl;
for(i=0;i < n;i++)
{for(j=0;j < n;j++)
{ cout < < g[i][j] < < " "; }
cout < < endl;
}

bool visited[100][100]; // this acts like a 1 to 1 mapping boolean matrix ( to mark if the node is visited ) */


cout < < "\nSolving by NN Constructive Heuristics (Greedy Approach)..." < < endl;

/* Setting all the cities (nodes) as NOT visited */
for(i=0;i < n;i++)
{
for(j=0;j < n;j++)
{
visited[i][j]=false;
}
}

long min=g[0][1],shortest=0; // initially choosing min as the second element of the 1st row , shortest is the total shortest path

int curr=0,temp=0,times=n-1; // times says the number of times the loop must exceute
i=0,j=0;

while(times > 0)
{

i=curr; // curr pointer points to the current row

for(int k=0;k < n;k++)
{
visited[k][curr]=true; // marking the current node as visited (logic: mark the whole column as visited )

}

for(int a=0;a < n;a++)
{
if(visited[curr][a]==false) // in the current row pointed by curr , set the min value as the first non visited distance in the matrix initially
{min=g[curr][a];break;}
}

for(j=0;j < n ;j++)
{

cout < < "i= " < < i < < " j= " < < j;
cout < < " Status of node (i,j) = " < < visited[i][j] < < " curr= " < < curr < < endl;

if(visited[i][j]==false)
{
if(g[i][j]==0 )
continue;

temp=g[i][j];

if(temp < =min) // finding the shortest path to its neighbours (logic: minimum value in the corresponding row )
{min=temp;curr=j;} // setting the curr pointer as the column in which min path is found
}


}



shortest+=min; // find the shortest path in each step and add to the final result
cout < < "Minimum path found after traversing city " < < i < < " = " < < min < < endl;
times--;
}
cout < < "Adding the Final Distance back to city 1 = " < < g[0][curr];

shortest+=g[0][curr];

cout < < endl < < "The minimum cost (96% - 100% correctness ) is " < < shortest < < endl;

system("PAUSE");
return 0;

}

Sunday, January 6, 2008

Hash Functions in a Nutshell


Hash Functions in a Nutshell

e05b477e0875325c9debf7591a5cb35b ...
Have I gone completely INSANE ? What on earth are those characters ? Doesn't make any sense ! Why should I start my article with some junk characters ? Well my friend, these characters are actually generated by many sophisticated algorithms and functions ! Though this concept is being used in almost every stream of Computer Science, yet many are unaware of “HASHING” !
In fact the junk characters mentioned at the beginning, is the hash of “ Welcome to the world of hashes !” by “md5”(Message Digest 5 ) hashing algorithm.

A hash function H can hence be defined as a transformation that takes a variable-size input m and returns a fixed-size string, which is called the hash value h (that is, h = H(m)).

So, no matter how large or small my input is , the output will always be of a fixed size (the output size varying from algorithms to algorithms.)At the end of the article I have mentioned some well known hash functions along with their output size for reference.
Since now you have a vague idea of the Hash functions , let us discuss about the most important properties of these functions. First of all, these functions are “Deterministic” , that is , for every unique input there is a corresponding unique fixed sized output. If the outputs are different , then their input must have been different in some way or another. Secondly these functions exhibit a very interesting and important property known as “Avalanche Effect”. To describe this property , lets take an example . Given below are two strings and their respective md5 hashes.

1)"I study in sastra university"
hash: 74ddb75b17ed110df1e6856389919165

2)"i study in sastra university"
hash: 64af04301652b62a41157e952ec9b281

Even if you are an average human being with average intelligence, you'd notice that the only difference in the two given strings are their first letter (inversion of the case of the letter ' I ' ). In spite of such a small difference in the strings , their outputs are very very different ! So to wrap it up in a nutshell “Even a small change in the input causes an enormous change in its output !”.This particular property is exploited in many fields , especially in cryptography , which is discussed later.

Thirdly, a well designed hash function is always “one way” , in contrast to most of the cryptographic algorithms, these functions are not reversible. That is there is no way to get back the original information from the output alone.

In spite of the above features, every hash function have seen to posses a major vulnerability, known as “collision”.A hash collision or hash clash is a situation that occurs when two distinct inputs into a hash function produce identical outputs. To minimize and prevent this , other algorithms are devised , such as cuckoo hashing,double hashing etc, which comes to rescue in case of a collision.

Hashes are widely used in cryptography,error correction and detection etc and most important , the concept of hashing is exploited to make a very efficient data structure, known as Hash Tables. “Lookup” time (time required to search for the corresponding value , given a key) is very efficient, which runs at a constant average time complexity of O(1). Hash tables provide more efficient insertion of new entries, which also runs at a time complexity of O(1).

When compared to normal tables, which runs at an average complexity of O(n) for both searching and insertion, Hash Tables are far more efficient and faster. Given above is a diagram of a simple hash table.

So you see, the “deterministic” property is actually exploited to create a very efficient table.
Now in case where there is a collision(which is rare) , several algorithms have been suggested to resolve in case of a collision such as linear probing,double hashing,perfect hashing etc. One of the widely used approach is called “cuckoo hashing” . It is a “greedy” approach which resolves a collision. The basic idea is to use two hash functions instead of only one. The values are knocked off from their fields and are placed in one of its two possible locations. This continues until all the values/data are placed , without any collision . This algorithm can also enter in an infinite loop, the hashes are recalculated for the whole table in that situation.

Coming to other application of hash functions , as I've already mentioned ... its mostly used in error detection (for instance CRC32 check), Network Security (for assigning distinct sessions),file verification , etc .

I'd show you a very nice example of file verification and integrity check , which is one the most important uses of the hash functions. For this, I've used an open source java software called “jacksum”. Lets consider that I have many files and folders kept in absolute path “f:\test”.
Lets look at the directory contents for a moment. (I'm using DOS , as many of you are more comfortable with it )

F:\test>dir
Volume in drive F is GooDieZ
Volume Serial Number is 3483-8838
Directory of F:\test

12/03/2004 10:29 PM 33,607,212 Evanescence - Haunted.mpg
12/23/2007 03:12 PM 23,098,768 iron maiden-dance of death-live.flv
11/21/2005 10:38 AM 42,027,012 lost prophets - last train home.mpg
12/16/2007 02:52 AM 16,425,004 megadeth-trust live.flv
01/03/2008 09:07 PM 30 test1.txt
5 File(s) 115,158,026 bytes
2 Dir(s) 3,165,220,864 bytes free

Now the first step is to create a “MetaFile”.This is a file which contains all the meta information (Hashes) of the files (Such as their hashes,directory,filename,date and time information etc).
For creating a meta file , “jacksum” accepts “-m” argument:
C:\jacksum-1.7.0>java -jar jacksum.jar -a "sha1+md5" -m -f -o "f:\test\meta.meta" "f:\test"
In the above command , I've instructed jacksum to use two algorithms (sha1 and md5) for creating the hashes of all the files and folders in the absolute path “f:\test”, and print the meta info data in the file “f:\test\meta.meta”

The meta data generated is something like this:

Jacksum: Meta-Info: version=1.7.0;algorithm=sha1+md5;filesep=\;encoding=hex;
Jacksum: Comment: created with Jacksum 1.7.0, http://jacksum.sourceforge.net
Jacksum: Comment: created on Thu Jan 03 21:22:40 PST 2008
Jacksum: Comment: os name=Windows XP;os version=5.1;os arch=x86
Jacksum: Comment: jvm vendor=Sun Microsystems Inc.;jvm version=1.6.0_03-b05
Jacksum: Comment: user dir=C:\Documents and Settings\Da G33k!\Desktop\jacksum-1.7.0
Jacksum: Comment: param dir=f:\test
6243ef97e06aca07bc09462b4301fdeb87f811a49792877e5f6591be6f1b4ebacc3f4525 33607212 f:\test\Evanescence - Haunted.mpg
567fd341f44c894fef69fddc6182aa5dea438e2f92490ca526c5f421ca3ceb37da69c8e8 23098768 f:\test\iron maiden-dance of death-live.flv
2c3f8aac837315275cc548c573045c752a54cb51fa461da701f2fd85f75879fb6dac13a2 42027012 f:\test\lost prophets - last train home.mpg
5ba983b3a524664fee752e4706786e0691bd4732da187d0c0499ecda331fb09d7863daad 16425004 f:\test\megadeth-trust live.flv
af9c077f4e3a25fd0c1c9d4c9dc6c6dbefaabc9faef02e0c887aabca3d29c6947a602367 30 f:\test\test1.txt

You can see that apart from the comments , the meta file has all the information needed for verification of the files in later stage.

Now in the next stage, lets verify the files in the same folder for any change. The following command does it:

C:\jacksum-1.7.0>java -jar jacksum.jar -c "f:\test\meta.meta"

Here I've instructed jacksum to check all the files against the meta file (The hashes of the files are generated again and are matched with those in the meta file). Note that i do not have to specify any additional information as all the necessary information is already listed in the meta file itself !

After pressing enter, I get the following output:

[OK] f:\test\Evanescence - Haunted.mpg
[OK] f:\test\iron maiden-dance of death-live.flv
[OK] f:\test\lost prophets - last train home.mpg
[OK] f:\test\megadeth-trust live.flv
[OK] f:\test\test1.txt

This means that all my files are intact and have not been changed.
Now let us assume that my file “test1.txt” has been accidentally changed or deleted. This would certainly mean that the hash of the file now , would be different than the hash of the file generated at the beginning(written in the meta file).

Lets do a check again . I give the same command as if given the last time and get the following output:

C:\jacksum-1.7.0>java -jar jacksum.jar -c "f:\test\meta.meta"
[OK] f:\test\Evanescence - Haunted.mpg
[OK] f:\test\iron maiden-dance of death-live.flv
[OK] f:\test\lost prophets - last train home.mpg
[OK] f:\test\megadeth-trust live.flv
[FAILED] f:\test\test1.txt

Thus the output explains everything , the file test1.txt has “failed” the verification test ! Tests like these are extremely useful in huge databases, where there is always a risk of accidental data manipulation.
I guess I've mentioned few of the most important applications , starting from the grass root level. Any comments or suggestions are always welcome ! Mail me at da.comp.guy@gmail.com :)

List of common cryptographic hash functions:

Name Output Length

HAVAL 128 to 256 bits
MD2 128 bits
MD4 128 bits
MD5 128 bits
SHA1 256 bits
SHA256 160 bits
SHA384 384 bits
SHA512 512 bits
WHIRLPOOL 512 bits

Friday, October 19, 2007

Configuring GRUB for linux newbies + Dual Booting Fundas ;)

These days i've been hearing a lot about "How can install dual OS in my system ? ".The answer is simple ... jus take the installation cd/dvd and install it one by one ! lol ! That might sound pretty simple and dumb ... but the real pain in ass is yet to come !
Configuring the BOOT LOADER is one of the most important job to be done .First of all lemme tell ya wat exactly a "boot loader" is.
Boot loader is something which gives over the control to the kernel of a 
specific OS. 
So after your computer starts , after the "POST"(Power On Self Test) , the first thing that operates is your boot loader.

GRUB(GRand Unified Bootloader)
is  the boot loader used in most of the linux systems. There also other boot loaders available like LILO.
Anyhow i'm not interested in telling about their history and stuffs, Lemme jump straight  to the point now...
Since i've already said what a boot loader is all about, lemme now tell something about the MBR.

MBR
stands for the Master Boot Record.As the name suggests, this is a part of the hard disk(always located in cylinder 0, head 0 
and sector1 of your hard disk)
 which contains the booting information. 

Now lets come to a practical scenario, where "roy" has installed "Fedora 7 linux" in his harddisk 1st and installed "Windows XP" next.He boots his pc and is extremely shocked to find out that no matter how hard he tries, he can not see any option to boot into linux !

Right, lets solve it now ! first lets analyze , why did it happen ? Well the answer to this is simple . Windows XP doesnt have a multi boot bootloader (For those who dint know, know it now ) ! It only has a couple of files such as NTLDR (New Technology Loader) to take care of booting its own OS.
But what about his linux ???? is it gone ?? Nah Dude ... Chill !!
Here's where GRUB comes in for rescue ! It's an awesome bootloader which loads of customizable options, recovery console, which can boot jus about any OS !

Now lets fix poor roy's problem.Here's wat you do ...

Step 1) Insert your linux rescue cd and boot in rescue mode
Step 2) Your linux distro will mount your system image automatically in some location (differs from distro to distro). If you are using Fedora, your image will be be mounted on
/mnt/sysimage
Step 3) change your root directory over to it . Just enter :
chroot /mnt/sysimage
Step 4) assuming your linux installation is in the firstsata/scsi drive, reinstall grub as follows:
grub-install /dev/sda

Note: for IDE drives the physical name will be /dev/hda . If your linux is in your second hard drive, it'll be /dev/hdb and so on...and for RAID users, it gets a bit complex, refer the man page for more details .

Step 5)After your boot loading information is mapped properly , you'll get a confirmation and then you can reboot !

Step 6) Woala .... !!! I can boot two OS'es now !!!!

But for solving more complex problems, you must have an in depth knowledge about GRUB. I can't tell u everything about it , but i'll sure list out the most important concepts.

Firstly GRUB and all its configuration files resides on /etc/grub .
The kernel and initrd (initial ram disk) stays  in /boot directory. Your might also also have a separate boot partition, which you can check out by a simple "fdisk -l" command .

To control GRUB's function you have to edit its's config  file, which resides in /etc/grub.conf

A typical configuration file looks like this:
-------------------------------------------------------------------------------------
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,1)
# kernel /vmlinuz-version ro root=/dev/hda3
# initrd /initrd-version.img
#boot=/dev/hda2
default=0
timeout=10
splashimage=(hd0,1)/grub/splash.xpm.gz

title Red Hat Linux (2.4.7-10)
root (hd0,1)
kernel /vmlinuz-2.4.7-10 ro root=/dev/hda3 hdc=ide-scsi
initrd /initrd-2.4.7-10.img

title Windows 2000
rootnoverify (hd0,0)
chainloader +1
------------------------------------------------------------------------------------

A few points about the configuration file now...
  • default = 0
This statement lets you define which OS to load by default, after the time out.
  • timeout = 10
This statement tells how long to wait for the user's choice ("press a key ..." and something like that..)
  • splashimage=(hd0,1)/grub/splash.xpm.gz
Here your can give the path to the GRUB's splash image . Note dat it must have an extension of xpm.gz ! the image must be edited to fit some constrain (8bit depth,14 colours 
and 640x480 size ).You can use the "convert" tool for converting your image.
  • title Red Hat Linux (2.4.7-10)
You can specify the title here
  • root (hd0,1)
This statement says where the root partition actually resides and mounts it accordingly. the (hd0,1) is your (harddisk,partition number).Please note that the partition actually starts from 0 here.So in case if you wanna know your partitionn number by "fdisk -l" , the partition number to be entered here is one less than the partition you actually saw in the "fdisk -l" output.
  • kernel /vmlinuz-2.4.7-10 ro root=/dev/hda3 hdc=ide-scsi
    initrd /initrd-2.4.7-10.img
These statements tells the path of kernel and initrd(which acts like a temporary storage for loading the kernel.)
  • rootnoverify (hd0,0)
This is similar to the "root(hd0,0)" but the only difference being that , this time it commands not to attempt to mount the partition. Which is kinda required for booting the windows systems.
  • chainloader +1
This means "start loading right from the 1st sectorin the specified partition". This is the way windows get loaded as NTLDR always starts from the 1st sector of the partition.
u can add comments in teh config file by puttin # in front of a line.

I guess i've added enough info for now, if u think i missed anything important, do lemme knw ! adios ... n happy booting .. ;D

For all dumbos... who still have'nt tried firefox... get a life !