Loading....
Coupon Accepted Successfully!

 

Question 1

Write a C program to swap two variables without using a temporary variable


This questions is asked almost always in every interview.

The best way to swap two variables is to use a temporary variable.


int a,b,t;

t = a;
a = b;
b = t;





There is no way better than this as you will find out soon. There are a few slick expressions that do swap variables without using temporary storage. But they come with their own set of problems.


Method1 (The XOR trick)


a ^= b ^= a ^= b;


Although the code above works fine for most of the cases, it tries to modify variable 'a' two times between sequence points, so the behavior is undefined. What this means is it wont work in all the cases. This will also not work for floating-point values. Also, think of a scenario where you have written your code like this



swap(int *a, int *b)
{
  *a ^= *b ^= *a ^= *b;
}



Now, if suppose, by mistake, your code passes the pointer to the same variable to this function. Guess what happens? Since Xor'ing an element with itself sets the variable to zero, this routine will end up setting the variable to zero (ideally it should have swapped the variable with itself). This scenario is quite possible in sorting algorithms which sometimes try to swap a variable with itself (maybe due to some small, but not so fatal coding error). One solution to this problem is to check if the numbers to be swapped are already equal to each other.


swap(int *a, int *b)
{
  if(*a!=*b)
  {
    *a ^= *b ^= *a ^= *b;
  }
}





Method2

This method is also quite popular


 a=a+b;
 b=a-b;
 a=a-b;



But, note that here also, if a and b are big and their addition is bigger than the size of an int, even this might end up giving you wrong results.



Method3

One can also swap two variables using a macro. However, it would be required to pass the type of the variable to the macro. Also, there is an interesting problem using macros. Suppose you have a swap macro which looks something like this


#define swap(type,a,b) type temp;temp=a;a=b;b=temp;



Now, think what happens if you pass in something like this


swap(int,temp,a) //You have a variable called "temp" (which is quite possible).



This is how it gets replaced by the macro


int temp;
temp=temp;
temp=b;
b=temp;



Which means it sets the value of "b" to both the variables!. It never swapped them! Scary, isn't it?


So the moral of the story is, dont try to be smart when writing code to swap variables. Use a temporary variable. Its not only fool proof, but also easier to understand and maintain.


Question 2

What is the 8 queens problem? Write a C program to solve it.


The 8 queens problem is a classic problem using the chess board. This problem is to place 8 queens on the chess board so that they do not attack each other horizontally, vertically or diagonally. It turns out that there are 12 essentially distinct solutions to this problem.


Suppose we have an array t[8] which keeps track of which column is occupied in which row of the chess board. That is, if t[0]==5, then it means that the queen has been placed in the fifth column of the first row. We need to couple the backtracking algorithm with a procedure that checks whether the tuple is completable or not, i.e. to check that the next placed queen 'i' is not menaced by any of the already placed 'j' (j

Two queens are in the same column         if t[i]=t[j]
Two queens are in the same major diagonal if (t[i]-t[j])=(i-j)
two queens are in the same minor diagonal if (t[j]-t[i])=(i-j)





Here is some working C code to solve this problem using backtracking


#include
static int t[10]={-1};
void queens(int i);
int empty(int i);

void print_solution();

int main()
{
  queens(1);
  print_solution();
  return(0);
}

void queens(int i)
{
  for(t[i]=1;t[i]<=8;t[i]++)
  {
    if(empty(i))
    {
       if(i==8)
       {
          print_solution();
          /* If this exit is commented, it will show ALL possible combinations */
          exit(0);
       }
       else
       {
          // Recurse!
          queens(i+1);
       }

    }// if

  }// for
}



int empty(int i)
{
  int j;
  j=1;

  while(t[i]!=t[j] && abs(t[i]-t[j])!=(i-j) &&j<8)j++;

  return((i==j)?1:0);
}



void print_solution()
{
  int i;
  for(i=1;i<=8;i++)printf("\nt[%d] = [%d]",i,t[i]);
}





And here is one of the possible solutions



t[1] = [1] // This means the first square of the first row.
t[2] = [5] // This means the fifth square of the second row.
t[3] = [8] ..
t[4] = [6] ..
t[5] = [3] ..
t[6] = [7] ..
t[7] = [2] ..
t[8] = [4] // This means the fourth square of the last row.



Question 3

How to generate fibonacci numbers? How to find out if a given number is a fibonacci number or not? Write C programs to do both.


Lets first refresh ourselves with the Fibonacci sequence


1, 1, 2, 3, 5, 8, 13, 21, 34, 55, .....


Fibonacci numbers obey the following rule


F(n) = F(n-1) + F(n-2)




Here is an iterative way to generate fibonacci numbers and also return the nth number.


int fib(int n)
{
   int f[n+1];
   f[1] = f[2] = 1;
 
   printf("\nf[1] = %d", f[1]);
   printf("\nf[2] = %d", f[2]);

   for (int i = 3; i <= n; i++)
   {
       f[i] = f[i-1] + f[i-2];
       printf("\nf[%d] = [%d]",i,f[i]);
   }
   return f[n];
}






Here is a recursive way to generate fibonacci numbers.


int fib(int n)
{
  if (n <= 2) return 1
  else return fib(n-1) + fib(n-2)
}






Here is an iterative way to just compute and return the nth number (without storing the previous numbers).


int fib(int n)
{
  int a = 1, b = 1;
  for (int i = 3; i <= n; i++) 
  {
     int c = a + b;
     a = b;
     b = c;
  }           
  return a;
}






There are a few slick ways to generate fibonacci numbers, a few of them are listed below


Method1

If you know some basic math, its easy to see that


         n
 [ 1 1 ]      =   [ F(n+1) F(n)   ]
 [ 1 0 ]          [ F(n)   F(n-1) ]



or


(f(n) f(n+1)) [ 0 1 ] = (f(n+1) f(n+2))
              [ 1 1 ]



or


                   n
(f(0) f(1)) [ 0 1 ]  = (f(n) f(n+1))
            [ 1 1 ]



The n-th power of the 2 by 2 matrix can be computed efficiently in O(log n) time. This implies an O(log n) algorithm for computing the n-th Fibonacci number.



Here is the pseudocode for this


int Matrix[2][2] = {{1,0}{0,1}}

int fib(int n)
{
    matrixpower(n-1);
    return Matrix[0][0];
}

void matrixpower(int n)
{
   if (n > 1) 
   {
      matrixpower(n/2);
      Matrix = Matrix * Matrix;
   }
   if (n is odd)
   {
      Matrix = Matrix * {{1,1}{1,0}}
   }
}




And here is a program in C which calculates fib(n)


#include 
  
int M[2][2]={{1,0},{0,1}}; 
int A[2][2]={{1,1},{1,0}}; 
int C[2][2]={{0,0},{0,0}};  // Temporary matrix used for multiplication.
  
void matMul(int n); 
void mulM(int m); 
  
int main() 

   int n; 
   n=6; 
      
   matMul(n-1); 

   // The nth fibonacci will be stored in M[0][0]
   printf("\n%dth Fibonaci number : [%d]\n\n", n, M[0][0]); 
   return(0); 




// Recursive function with divide and conquer strategy

void matMul(int n)

   if(n>1) 
   { 
     matMul(n/2); 
     mulM(0);     // M * M
   } 
   if(n%2!=0) 
   { 
    mulM(1);     //  M * {{1,1}{1,0}}
   } 

  

// Function which does some basic matrix multiplication.

void mulM(int m) 

   int i,j,k; 
  
   if(m==0) 
   { 
     // C = M * M

     for(i=0;i<2;i++) 
      for(j=0;j<2;j++) 
      { 
        C[i][j]=0; 
        for(k=0;k<2;k++) 
           C[i][j]+=M[i][k]*M[k][j]; 
      } 
   } 
   else 
   { 
     // C = M *  {{1,1}{1,0}}

     for(i=0;i<2;i++) 
      for(j=0;j<2;j++) 
      { 
        C[i][j]=0; 
        for(k=0;k<2;k++) 
         C[i][j]+=A[i][k]*M[k][j]; 
      } 
   } 

   // Copy back the temporary matrix in the original matrix M

   for(i=0;i<2;i++) 
     for(j=0;j<2;j++) 
     { 
       M[i][j]=C[i][j]; 
     } 
}  





Method2


f(n) = (1/sqrt(5)) * (((1+sqrt(5))/2) ^ n - ((1-sqrt(5))/2) ^ n)




So now, how does one find out if a number is a fibonacci or not?.

The cumbersome way is to generate fibonacci numbers till this number and see if this number is one of them. But there is another slick way to check if a number is a fibonacci number or not.


N is a Fibonacci number if and only if (5*N*N + 4) or (5*N*N - 4) is a perfect square!



Dont believe me?


3 is a Fibonacci number since (5*3*3 + 4) is 49 which is 7*7
5 is a Fibonacci number since (5*5*5 - 4) is 121 which is 11*11
4 is not a Fibonacci number since neither (5*4*4 + 4) = 84 nor (5*4*4 - 4) = 76 are perfect squares.



To check if a number is a perfect square or not, one can take the square root, round it to the nearest integer and then square the result. If this is the same as the original whole number then the original was a perfect square.


Question 4

Solve the Rat In A Maze problem using backtracking.


This is one of the classical problems of computer science. There is a rat trapped in a maze. There are multiple paths in the maze from the starting point to the ending point. There is some cheese at the exit. The rat starts from the entrance of the maze and wants to get to the cheese.

This problem can be attacked as follows.

 

  • Have a m*m matrix which represents the maze.
  • For the sake of simplifying the implementation, have a boundary around your matrix and fill it up with all ones. This is so that you know when the rat is trying to go out of the boundary of the maze. In the real world, the rat would know not to go out of the maze, but hey! So, initially the matrix (I mean, the maze) would be something like (the ones represent the "exra" boundary we have added). The ones inside specify the obstacles.


    111111111111111111111
    100000000000000000001
    100000010000000000001
    100000010000000000001
    100000000100001000001
    100001000010000000001
    100000000100000000001
    100000000000000000001
    111111111111111111111


     
  • The rat can move in four directions at any point in time (well, right, left, up, down). Please note that the rat can't move diagonally. Imagine a real maze and not a matrix. In matrix language

    • Moving right means adding {0,1} to the current coordinates.
    • Moving left means adding {0,-1} to the current coordinates.
    • Moving up means adding {-1,0} to the current coordinates.
    • Moving right means adding {1,0} to the current coordinates.
  • The rat can start off at the first row and the first column as the entrance point.
  • From there, it tries to move to a cell which is currently free. A cell is free if it has a zero in it.
  • It tries all the 4 options one-by-one, till it finds an empty cell. If it finds one, it moves to that cell and marks it with a 1 (saying it has visited it once). Then it continues to move ahead from that cell to other cells.
  • If at a particular cell, it runs out of all the 4 options (that is it cant move either right, left, up or down), then it needs to backtrack. It backtracks till a point where it can move ahead and be closer to the exit.
  • If it reaches the exit point, it gets the cheese, ofcourse.
  • The complexity is O(m*m).


Here is some pseudocode to chew upon


findpath()
{
  Position offset[4];
  Offset[0].row=0; offset[0].col=1;//right;
  Offset[1].row=1; offset[1].col=0;//down;
  Offset[2].row=0; offset[2].col=-1;//left;
  Offset[3].row=-1; offset[3].col=0;//up;

  // Initialize wall of obstacles around the maze
  for(int i=0; i     maze[0][i] = maze[m+1][i]=1; maze[i][0] = maze[i][m+1]=1;

  Position here;
  Here.row=1;
  Here.col=1;

  maze[1][1]=1;
  int option = 0;
  int lastoption = 3;

  while(here.row!=m || here.col!=m)
  {
     //Find a neighbor to move
     int r,c;

       while (option<=LastOption)
       {
          r=here.row + offset[position].row;
          c=here.col + offset[option].col;
          if(maze[r][c]==0)break;
          option++;
       }

       //Was a neighbor found?
       if(option<=LastOption)
       {
         path->Add(here);
         here.row=r;here.col=c;
         maze[r][c]=1; 
         option=0;
       }
       else
       {
          if(path->Empty())return(False);
          Position  next;
          Path->Delete(next);
          If(new.row==here.row)
             Option=2+next.col - here.col;
          Else { option = 3 + next.row - here.col;}
             Here=next; 
       }
       return(TRUE);
  }
}



Question 5

What Little-Endian and Big-Endian? How can I determine whether a machine's byte order is big-endian or little endian? How can we convert from one to another?


First of all, Do you know what Little-Endian and Big-Endian mean?

Little Endian means that the lower order byte of the number is stored in memory at the lowest address, and the higher order byte is stored at the highest address. That is, the little end comes first.

For example, a 4 byte, 32-bit integer


    Byte3 Byte2 Byte1 Byte0


will be arranged in memory as follows:


    Base_Address+0   Byte0   
    Base_Address+1   Byte1   
    Base_Address+2   Byte2   
    Base_Address+3   Byte3   



Intel processors use "Little Endian" byte order.


"Big Endian" means that the higher order byte of the number is stored in memory at the lowest address, and the lower order byte at the highest address. The big end comes first.


  Base_Address+0   Byte3
  Base_Address+1   Byte2
  Base_Address+2   Byte1
  Base_Address+3   Byte0



Motorola, Solaris processors use "Big Endian" byte order.

In "Little Endian" form, code which picks up a 1, 2, 4, or longer byte number proceed in the same way for all formats. They first pick up the lowest order byte at offset 0 and proceed from there. Also, because of the 1:1 relationship between address offset and byte number (offset 0 is byte 0), multiple precision mathematic routines are easy to code. In "Big Endian" form, since the high-order byte comes first, the code can test whether the number is positive or negative by looking at the byte at offset zero. Its not required to know how long the number is, nor does the code have to skip over any bytes to find the byte containing the sign information. The numbers are also stored in the order in which they are printed out, so binary to decimal routines are particularly efficient.


Here is some code to determine what is the type of your machine


int num = 1;
if(*(char *)&num == 1)
{
  printf("\nLittle-Endian\n");
}
else 
{
  printf("Big-Endian\n");
}




And here is some code to convert from one Endian to another.



int myreversefunc(int num)
{
  int byte0, byte1, byte2, byte3;    

  byte0 = (num & x000000FF) >>  0 ;
  byte1 = (num & x0000FF00) >>  8 ;
  byte2 = (num & x00FF0000) >> 16 ;
  byte3 = (num & xFF000000) >> 24 ;

  return((byte0 < }



Question 6

Write C code to solve the Tower of Hanoi problem.


Here is an example C program to solve the Tower Of Hanoi problem...


main()
{
    towers_of_hanio(n,'L','R','C');
}

towers_of_hanio(int n, char from, char to, char temp)
{
    if(n>0)
    {
        tower_of_hanio(n-1, from, temp, to);
        printf("\nMove disk %d from %c to %c\n", n, from, to);
        tower_of_hanio(n-1, temp, to, from);
    }
}



Question 7

Write C code to return a string from a function


This is one of the most popular interview questions

This C program wont work!


char *myfunction(int n)
{
   char buffer[20];
   sprintf(buffer, "%d", n);
   return retbuf; 
}




This wont work either!


char *myfunc1()
{
  char temp[] = "string";
  return temp;
}


char *myfunc2()
{
   char temp[] = {'s', 't', 'r', 'i', 'n', 'g', '\0'};
   return temp;
}


int main()
{
    puts(myfunc1());
    puts(myfunc2());
}





The returned pointer should be to a static buffer (like static char buffer[20];), or to a buffer passed in by the caller function, or to memory obtained using malloc(), but not to a local array.

This will work


char *myfunc()
{
   char *temp = "string";
   return temp;
}

int main()
{
   puts(someFun());
}




So will this


calling_function()

  char *string; 
  return_string(&string); 
  printf(?\n[%s]\n?, string);
}

boolean return_string(char **mode_string /*Pointer to a pointer! */) 

   *string = (char *) malloc(100 * sizeof(char)); 
   DISCARD strcpy((char *)*string, (char *)?Something?); 
}



Question 8

Write a C program which produces its own source code as its output


This is one of the most famous interview questions

One of the famous C programs is...


char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);}


So how does it work?

It's not difficult to understand this program. In the following statement,


printf(f,34,f,34,10); 


the parameter "f" not only acts as the format string, but also as a value for the %s specifier. The ASCII value of double quotes is 34, and that of new-line is 10. With these fact ready, the solution is just a matter of tracing the program.


Question 9

Write a C progam to convert from decimal to any base (binary, hex, oct etc...)


Here is some really cool C code


#include 

int main()
{
  decimal_to_anybase(10, 2);
  decimal_to_anybase(255, 16);
  getch();
}

decimal_to_anybase(int n, int base)
{
  int i, m, digits[1000], flag;
  i=0;
  
  printf("\n\n[%d] converted to base [%d] : ", n, base);
  
  while(n)
  {
     m=n%base;
     digits[i]="0123456789abcdefghijklmnopqrstuvwxyz"[m];
     n=n/base;
     i++;
   }

   //Eliminate any leading zeroes
   for(i--;i>=0;i--)
   {
     if(!flag && digits[i]!='0')flag=1;
     if(flag)printf("%c",digits[i]);
   }   
}




Question 10

Write C code to check if an integer is a power of 2 or not in a single line?


Even this is one of the most frequently asked interview questions. I really dont know whats so great in it. Nevertheless, here is a C program

Method1


if(!(num & (num - 1)) && num)
{
  // Power of 2!
}



Method2


if(((~i+1)&i)==i)
{
 //Power of 2!
}



I leave it up to you to find out how these statements work.






Test Your Skills Now!
Take a Quiz now
Reviewer Name