Showing posts with label mistakes. Show all posts
Showing posts with label mistakes. Show all posts

Monday, August 9, 2010

Interview question: Find if word exists in a crossword

In my preparation for google interview, I thought I should go over some problem in career cup and I found this crossword problem pretty interesting. In my mock interview yesterday I later found a simpler solution using an intuitive recursion, so I thought I should try this problem.

The problem statement is:

Given a puzzle of letters/ characters e.g.

a e r o p s

b h a r l s

w r i s l o

a s n k t q

Write a function to which this puzzle and a word will be passed to test whether that word exists in the puzzle or not.

e.g. rain and slow will return true. rain is present in the second column and slow in the third row wrapped around.


 

This problem reminded me of maze exploration which can be done recursively and I started coding in that mode.

  • First I would have a main recursive function which checks if the first word matches

    private boolean stringFinder(char[][] ar, String str) {

            int size=ar.length;

            if(str.length()>size+1) return false;

            int k=0;

            char[] charArray=str.toCharArray();

            for(int i=0;i<size;i++)

                for(int j=0;j<size;j++)

                    if(ar[i][j]==charArray[k])

  • If matches recursively check all the four directions

    return isMatch(ar,charArray,i,((j+1)%size),k+1)||

                        isMatch(ar,charArray,((i+1)%size),j,k+1)||

                        isMatch(ar,charArray,((i-1)%size),j,k+1)||

                        isMatch(ar,charArray,i,((j-1)%size),k+1);

  • In each of the directions again search for a match. (this is wrong)

    private boolean isMatch(char[][] ar, char[] charArray, int i, int j, int k, Direction dir) {

            int size=ar.length;

            if(k==charArray.length-1)

            {

                if(ar[i][j]==charArray[k]) return true;

                else return false;

            }

            if(ar[i][j]==charArray[k])

                return isMatch(ar,charArray,i,((j+1)%size),k+1)||

                        isMatch(ar,charArray,((i+1)%size),j,k+1)||

                        isMatch(ar,charArray,((i-1)%size),j,k+1)||

                        isMatch(ar,charArray,i,((j-1)%size),k+1);

            }

            return false;

        }

    I verified this approach and it was working with pen and paper. So I opened up eclipse with a jolly mood and though I am a genius.

But there were several mistakes

  • When the inevitable happened- the program is not responding as expected, I found that I am searching in all direction after I found a direction. So I modified my approach to include a direction enum.
  • And tried to change i and j values based only on the direction. This time I got the directions wrong and it took a while to overcome it.
  • Then I got the problem of comparing next recursion when I wanted to be in the current one. So I changed the order.
  • Finally I got the result when I send in "rain" and the output is true ! And then I again checked for "slow" and magic it returned true!!
  • But when I am sending in a string that does not exist I am getting an exception. Reason: I am sending in negative indexes.. Even though I am wrapping i and j values I forgot to take of –ve signs.

    So finally my code became like this


     

    package com.code.prolificcoder;


     

    public class StringFinder {

        enum Direction{up,down,left,right};

        public static void main(String args[]){

            char[][] ar=new char[][]{{'m','s','s','h'},

                                     {'a','t','c','i'},

                                     {'p','d','a','n'},

                                     {'s','a','t','h'},

                                    };

            String str="tcia";

            StringFinder sf=new StringFinder();

            System.out.print(sf.stringFinder(ar,str));

            }


     

        private boolean stringFinder(char[][] ar, String str) {

            int size=ar.length;

            if(str.length()>size+1) return false;

            int k=0;

            char[] charArray=str.toCharArray();

            for(int i=0;i<size;i++)

                for(int j=0;j<size;j++)

                    if(ar[i][j]==charArray[k])

                        return isMatch(ar,charArray,i,Math.abs((j+1)%size),k+1,Direction.right)||

                        isMatch(ar,charArray,Math.abs((i+1)%size),j,k+1,Direction.down)||

                        isMatch(ar,charArray,Math.abs((i-1)%size),j,k+1,Direction.up)||

                        isMatch(ar,charArray,i,Math.abs((j-1)%size),k+1,Direction.left);

            return false;

        }


     

        private boolean isMatch(char[][] ar, char[] charArray, int i, int j, int k, Direction dir) {

            int size=ar.length;

            if(k==charArray.length-1)

            {

                if(ar[i][j]==charArray[k]) return true;

                else return false;

            }

            if(ar[i][j]==charArray[k]){

                if(dir==Direction.down)

                    i=Math.abs((i+1)%size);    

                else if(dir==Direction.right)

                    j=Math.abs((j+1)%size);    

                else if(dir==Direction.left)

                    j=Math.abs((j-1)%size);

                else //dir==Direction.up

                    i=Math.abs((i-1)%size);

            

                return isMatch(ar,charArray,i,j,k+1,dir);

            }

            
     

            

            return false;

        }


     

        
     

        

    }


     

    It took me more than 2 hours to get this version, in an interview you are not given this many chances and a compiler and a debugger. I should be able to correct my bugs in walkthroughs, all in all scary.

    Update: My tester wife found another bug in this code. Whenever there is a search for a char that is present twice I am returning the result of the first one which could be false but the later could be true.

    For eg: "scat" in the above it will return false because the first match for s resulted in false and I returned it. To solve this I update the code as follows.

private
boolean stringFinder(char[][] ar, String str) {

        int size=ar.length;

        if(str.length()>size+1) return
false;

        int k=0;

        boolean found=false;

        char[] charArray=str.toCharArray();

        for(int i=0;i<size;i++)

            for(int j=0;j<size;j++)

                if(ar[i][j]==charArray[k])

                    found= isMatch(ar,charArray,i,Math.abs((j+1)%size),k+1,Direction.right)||

                    isMatch(ar,charArray,Math.abs((i+1)%size),j,k+1,Direction.down)||

                    isMatch(ar,charArray,Math.abs((i-1)%size),j,k+1,Direction.up)||

                    isMatch(ar,charArray,i,Math.abs((j-1)%size),k+1,Direction.left)||found;

        return found;

    }

Wednesday, August 4, 2010

How not to do a technical phone interview

Today I had a phone screen from a good startup from NY, even though at the time I felt I aced the interview on second thoughts I think I will not hear back from them. I actually took the call from skype and used a tool called call burner to record my performance.
After going through it I am not impressed at all, its not a tough interview but I managed to stumble or blunder couple of times.
Ok, listing my mistakes in order of worstness and why I made them.
  1. Got the technical question completely wrong. The question is "How would you reverse a string without using a for loop". To be honest I was expecting a simpler question this question kind of got be off guard. So, I asked if I can use a while loop, he goes to say that I can't use a iterator. Then I got this idea of swapping start and end pointers until start <= end and he did not object to it. But on later thoughts I think he gave up on me, what he is actually looking for a recursion based solution. Its not simple or intuitive but a recursive solution can be made.
  2. What is the difference between abstract class and interface, I have been asked this question probably 5 times in an interview now and I can't explain why I stumbled today. I was talking about implementing an abstract class etc.. while the main difference is in how many of them a class can use. A class can have multiple interfaces but can only have one parent class. Though I knew it I didn't say it.
  3. I didn't get the company website before the interview, I actually didn't understand so I couldn't look at it.
I did some things ok and explained somethings good but overall it was an uninspiring performance. All in all I think it will be miracle if I am invited to onsite.

So what went wrong
  1. I didn't take time when I have to a)while solving the problem b)while constructing sentences. I really don't understand my rush during the phone interview.
  2. I am not getting the attitude of its ok to pause before attempting to say something. It creates a bad impression to mumble something than to pause a while and say something more coherent.
I hope I learn from this experience and would do better in future interviews.