Buddha

Buddha
Seek

Wednesday, March 4, 2015

Magic Words.

Magic words can be described as below.

Given a list of words L, a word is considered magical, if it can be reduced to a starting root alphabet, recursively, by stripping off one character at a time, and the newly formed word is also present in the list L.

Lets assume the root alphabet is 'A'. So 'A' should be present in the list.

[A]

Now with one word added anywhere, we can have the following magic words.

A[A..Z]
[A..Z]A

Lets pick 2 magic words for our list and extend it.

[A, AN, SA]

To our list we will add a non-magic word.

[A, AN, SA, BC]

Lets extend with some more magic words to clarify the problem.

AN -> ANT
AN -> BAN
SA -> RSA
SA -> SAS
SA -> SPA

BC (non-magic) -> ABC

So new lists looks like
[A, AN, SA, BC, ANT, BAN, RSA, SAS, SPA, ABC]

The point to note here is ABC is not a magic word, as all the sub words ( AB, AC, BC ) are non existent in the list, hence there is no way to recursively reach 'A' by reducing 'ABC' using words present in the list.

Problem : 
Given a list of words, find the longest magic word. Assume the root alphabet is always present.

Solution :
Considerations :

As we are trying to find the longest word, we can start off by arranging all the words by decreasing length and check from the longest word if it is magical or not.

Python Code.

 wordList = ["a","an","san","sans","saxds","man","said","salds","aid","axds"]
 def modifyWord(elem):
     list_of_chars = list(elem)
     if len(list_of_chars) == 1:
        return 1
     for index in range(len(list_of_chars)):
        newWordList = list_of_chars[:index] + list_of_chars[index+1:] #check for bounds
        newWord = "".join(newWordList)
        #print newWord
        if newWord in wordList:
            retVal = modifyWord(newWord)
            if retVal:
                return 1 + retVal
            else:
                return 0
     return 0

 if __name__ == '__main__':
     len_sorted_wordList = sorted(wordList, key=len, reverse=True)
     for elem in len_sorted_wordList:
        print "Elem = ", elem
        maxlen = max(0, modifyWord(elem))
        if maxlen:
            print maxlen
            break

In the above code, lets understand the function modifyWord.

The modifyWord takes as an input a word element, and converts it into a list of characters first. If the length is 1, it simply returns the length. So if we pass a root alphabet, we get a return value of '1'.
Otherwise, the code removes a character one at a time and forms the newWord. Now we check if the newWord is in the original list. If present , we call modifyWord on it again, else, we try the same on the next newWord, formed by removing the next index element. The commented print statement is there to show what the newWord looks like.

If you have better solutions please comment, I would love to know. Also other modifications can be, to create a sorted tree from the list using the root alphabet as the root element, to find magic words from a start word rather than a root alphabet, etc.

Tuesday, January 27, 2015

Find Decimal value from a Roman Numeral Number , iterative and recursive solutions

The problem : Given a roman value, find the corresponding decimal value.

Sample Input : XVII
Sample Output : 17

Sample Input : XIV
Sample Output : 14

Solution:

If we first look, there are certain roman values representing certain decimal values, direct mapping, cant do anything about that. So we need a map. Like the one below

map = {'I':1, 'V':5 , 'X':10, 'L':50, 'C':100}

Next gotcha, as long as the values are decreasing or constant, with index, we just keep adding the values. However, if the values increase, we need to do things differently. What needs to be done differently ? We need to subtract the lower value from higher value.

e.g.  if number is VI , index 0 has ' V ' and index 1 has ' I ' , values are decreasing, we need to add value of V + value of I , which is, 5 + 1 = 6

if number is IV, index 0 has ' I ' and index 1 has ' V ' which is increasing, we need to do value of V - value of I , which is 5 - 1 =  4

So, in general, we need to know the next Value.

Iterative Solution:

def returndec(roman):
charlist = list(roman)
num = 0
for i in range(len(charlist)):
if i+1 == len(charlist):
num += map[charlist[i]]
else:
if map[charlist[i]] >= map[charlist[i+1]]:
num += map[charlist[i]]
else:
num -= map[charlist[i]]
return num

Here, we see that indexes i and i+1 are being compared as long as i+1 is in bounds. If the order is decreasing we do  num = num - charlist[i] , which is essentially, adding up negative of lower value to higher value, which is in other words subtracting lower value from higher value.

The recursive solution gets more interesting. Here we need to track the sum as we toss it to each function as a param, but when we return , we need to return the sum, as well as value of first index. Let me demonstrate:

for roman number "XIX"

To calculate func("XIX") we need to calculate either
a)  X + func("IX")
OR
b) -X + func ("IX")

depending on whether X is greater than I or not

Recursive Solution:

def returnDecRec(roman , num):
print "roman ", roman, " num ", num
if not roman:
return (num, 0)
val = map[list(roman)[0]]
num, lastVal = returnDecRec(roman[1:], num)
if lastVal > val:
return (num - val, val)
else:
return (num + val, val)

In the above case, we return sum until the subset of string, plus value added.
Another way to recurse would be to pass the value added in the function parameter.

Something like :
def returnDecRec(roman, num, val)

Tuesday, September 13, 2011

Ways to import a python module with differences.

I was always confused between the subtleties of

import X

from X import *

import X as Y

__import__("X")

This (by effbot) is a nice link which explains the intricacies.

Saturday, April 2, 2011

Reversing a singly linked list using recursion aka Recursively link reversal

The code to reverse a singly linked list using iteration is trivial, using the three pointer method. Lets have a look at the method to reverse a linked list recursively. Not only this is fast, but clears your pointer concepts if you think it cleanly.

Lets define the function.

It would be something like this:

Node* reverseList(Node** head)


This means we are passing the address of the pointer pointing to the head node. We do so, because this is where we want to store the return address. Every time we recurse, we do the following:


1. store the current head in a new variable called now.
2. check if we are at the end of list
3. if we are, we just return
4. if we arent, we collect the newhead from the rest of the list
5. we point the now->next->next  (now which we stored in 1) to now.
6. we make now->next = NULL.

  Node* reverseList(Node **head) {
if (*head == NULL)
return NULL;
Node *now = *head;
Node *newhead = NULL;
if((*head)->next == NULL)
return *head;
else
newhead = reverseList(&((*head)->next));
now->next->next = now;
now->next = NULL;
return newhead;
}


Lets consider an example 1->2->3->4->NULL


Call 1:
*head points to 1
saved *head into now, so now points to 1
newhead = NULL
enter the else, recurse, i.e. reverseList(2)


Call 2
*head points to 2
saved *head into now, so now points to 2
newhead = NULL
enter the else, recurse, i.e. reverseList(3)

Call 3
*head points to 3
saved *head into now, so now points to 3
newhead = NULL
enter the else, recurse, i.e. reverseList(4)

Call 4
*head points to 4
saved *head into now, so now points to 3
head->next = NULL
enter the if, return from Call 4

Return into Call 3
newhead now stores *head = 4
now = 3
now->next = 4
now->next->next = now  means we set  3 <- 4
now->next = NULL  means we set NULL <- 3 <- 4
return newhead, i.e. 4

Return into Call 2
newhead now stores  4
now = 2
now->next = 3
now->next->next = now  means we set  2 <- 3 <- 4
now->next = NULL  means we set NULL <- 2 <- 3 <- 4

Return into Call 1
newhead now stores  4
now = 1
now->next = 2
now->next->next = now  means we set  1 <- 2 <- 3 <- 4
now->next = NULL  means we set NULL <- 1 <- 2 <- 3 <- 4

we return newhead




Thursday, March 3, 2011

Arrow keys not working properly on terminal

Arrow keys did not seem to be doing what they were supposed to with a few applications. With cscope it wasn't going up and down the menu items. Instead when I pressed the keys, it was giving a whole lot of control characters. With yast2, the arrow keys wouldn't simply make the cursor move. The system was a Suse Linux Enterprise Edition box. I was trying to figure out what makes it move on Ubuntu(my other box) and not on SLES.

The fix was simple. Found out that its the way different terminals handle arrow keys.

If you try echo $TERM on your shell, it showed me something like, xtermc. I replaced the value like below:

export $TERM="vt100"

This simply worked. Now my arrow keystrokes are identified properly. More on text based terminals here.

Thursday, February 24, 2011

Interview Questions - 3

Google Interview Questions.

Interview Type: Telephonic
Interview Duration: 30 mins

1. What is the default signal generated by kill command ?

2. What is a sticky bit ?

3. Given a path, which system call returns the information about the inode ?

4. Given 10000 16 bit integers, and unlimited memory, what is the quickest way to count the total number of bits set in the array.

5. Given four operations
a. Read from CPU reg
b. Disk Seek
c. Context switch
d. Read from main memory

Rank them in order of speed.

6. Average case and worst case running time for quick sort.

7. What is the opposite of malloc in C.

8. Value of "a"[3 >> 1]

Wednesday, February 23, 2011

Interview Questions - 2

Some more questions:

Type: Data Structures
Company Type: Web, Software, e-Commerce

1. Given is a linked list, in which the Node data is the address of another node (e.g. Data of node 3 is storing address of node 5, data of node 5 is storing address of node 2, etc). How can you copy this linked list ?

Catch is when you copy memory changes, hence the data should change accordingly.

2. Given a Directed Graph, design an algorithm which can detect if there is a loop or not.

3. Given a Binary tree, where each node stores a certain value, find the average at the node.

4. Given an unsorted array, a number 'k', find how many pairs in the array sum up to the value 'k' in the most efficient way. Time complexity should be O(n).

5. Given 2 sorted arrays, and 1 array big enough to accomodate the other array [enough empty space], write a program to get the final array in O(m+n).

Tuesday, February 22, 2011

Interview Questions - 1

Interview Month: February
Interview Position: Software Engineer
Interview Duration: About 30 minutes
Interview Company Type: Networking

1. Whats the library used for threading in C on Unix based systems ?

2. What is the pthread library call used to create a new thread and the parameters to the call?

3. How do you think the pthread_lock() is implemented ?

4. Will this work for multi processor/core systems also ? {This question asked in many interviews}
Dont know a proper answer to this question yet. Any links would be helpful.

5. What is malloc? System call or Library Call? Why?

6. At what times does malloc invoke a system call? Does it always invoke?
Answer is something regarding maintaining buckets. Check out malloc implementation details

7. What is a hash-map data structure? How does it store data?

8. Advantages and disadvantages of using a hashmap. Give examples of systems where you would not use 1.

Friday, February 18, 2011

And I am back....

The desire to key my thoughts couldn't keep me away from here.

Hey everyone, look I am back.

Thursday, July 22, 2010

Bloody Hell

I have been trying to give it a thought, but I am tired now. I need some1 to design a proper looking frontpage for my website which has a lot of space and holds absolutely nothing. Bah !!

Rain ideas, good Lord.

Oh yeah, I plan to post my Bahamas pics there. :D

SVN problems over the web

The other day I was configuring my SVN over Apache for my Lab server. I had almost set it up and it was almost looking perfect when it failed to commit. So everytime i tried to commit it would give me this strange looking error.

svn: Commit failed (details follow):
svn: Server sent unexpected return value (500 Internal Server Error) in response to MKACTIVITY request for '/repos/testrep/!svn/act/b5cf039a-95ed-11df-a9f1-a38cb1af4ec0'


I am running SLES 11 and my web server runs on a virtual host and this was my subversion.conf file [relevant section] located at /etc/apache2/conf.d/subversion.conf :



DAV svn
SVNParentPath /srv/svn/repos/
SVNListParentPath On

AuthType Basic
AuthName "Commiting to repository requires a password"
AuthUserFile /srv/svn/user_access/svn_passwdfile
Require valid-user



So after a lot of trial and error and in an attempt not to make a fool of myself before the professor, I tried changing the line in my subversion.conf to this:



The old error was gone, but a new error showed up

So my final modified line ended up looking like this.



And then it worked like cream.

How I came up with the idea? It was after I read stuff from here

Friday, January 16, 2009

Man !!

It was a bright sunny day. I was drowsing, on my chair, with my head swaying from left to right like a pendulum with a frequency much slower than of a grandpa clock pendulum.

Suddenly I dreamt of coding. Wham !! I woke up, got my coffee and sat to work.

Damn. I was supposed to write some network shit. I realized I had swallowed the taste of network system calls. So I issued a man command:

Wabbit@ubuntu:~$ man accept
No manual entry for accept

What the fuck man ?

If you face such a problem, download and put the manpages-dev package

root@ubuntu:~# aptitude install manpages-dev

And it was done !!

Ahem!! So I coded.

Tuesday, September 9, 2008

gdm was not starting on bootup

I had a sudden problem, I dunno how I came to it, but my gdm never started up when my laptop was booting.So the login process was not only long but damn boring as well, which included, inputting your password thrice :)

So I decided to change it. What I did was opened the dir /etc/rc5.d and edited the shell script named S30gdm and changed the value of

HEED_DEFAULT_DISPLAY_MANAGER=false (from true)

Then it worked for me ;)

gdm was not starting on bootup

I had a sudden problem, I dunno how I came to it, but my gdm never started up when my laptop was booting.So the login process was not only long but damn boring as well, which included, inputting your password thrice :)

So I decided to change it. What I did was opened the dir /etc/rc5.d and edited the shell script named S30gdm and changed the value of

HEED_DEFAULT_DISPLAY_MANAGER=false (from true)

Then it worked for me ;)

Sunday, August 31, 2008

Problem with Flash Player in Firefox 3.0, Ubuntu 8.04

Well there was a small problem with my Firefox, I had installed some flash player, which asked me to click the flash video in the page to enable it. I had installed libflashplayer.so as well, but it was always running the other library for flash-shockwave, i.e. libswfdecmozilla.so . Well I got it working.

Steps I followed are quite simple. I ran about:plugins on the firefox address bar, looked for the names of the .so player for playing flash and shockwave. I found the files in my system and removed all of them except , libflashplayer.so

Usually you can find the .so files in /usr/lib

Not it rocks

- Wabbit

Tuesday, June 24, 2008

Syntax highlighting on VIM

Hi,

Well wont you love to have the syntax/color highlighted in VI editor. Be it a C program or HTML, vim is a classy editor and of course we would love to have syntax highlighted on it.

Aint it ??

How to go ahead and achieve it.

The easiest way - in vim press :

the type 'syntax on'

To do it everytime the editor comes up automatically.

Search for a file called vimrc.
Generally it would be somewhere like /etc/vim/vimrc

Open the file and uncomment the line

"syntax on
to
syntax on [remove whatever is before that]

Play around, make changes, then next time vim is started, syntax is highlighted.

Follow: http://www.ph.unimelb.edu.au/~ssk/vim/syntax.html for actual documentation.


Chao.

Monday, June 2, 2008

How to export X display using Cygwin

Hi.
For most of those who would want to connect from a Windows machine on to a Linux/Solaris/Unix server and have the display imported, here is the method.

1. Download and install cygwin on windows.
2. After the installation is complete, run a cygwin bash shell.
3. type the following commands there

x -multiwindow&
export DISPLAY=[IP of ur machine]:0.0 [for me it was export DISPLAY=10.114.55.119:0.0]
xhost +


4. Telnet to the remote machine and set the DISPLAY variable with your machine's IP
export DISPLAY=[IP of local machine]:0.0

5. start any application in the background.
firefox&

Monday, May 26, 2008

Steps for configuring Apache HTTP Daemon on Solaris x86

- Get the source code and untar it and then enter the directory.
- run configure
- run make
- run make install
- become super user
- export the binary path [ /usr/local/apache2/bin ]
- export the libraries path [ /usr/local/lib and /usr/lib]
- edit the Group# from Group# -1 to Group# 0 [ for root ] in /usr/local/apache2/conf/httpd.conf
- edit the Username from nobody to ‘smoke’ in the same file, although leaving this untouched does not cause any problem [ It is recommended by the online manual to create a new user to run the server , and not to set the user as root ]
- run apachectl start
- run firefox and open the link http://localhost which tells about the status of the server.
- for logs look into /usr/local/apache2/logs

Thursday, February 14, 2008

Starting an App with GNOME Startup

There are times when you would like to start certain app when GNOME
starts up. This is just like the Windows Startup program. In Windows
[Win XP] we used to place the links to the programs in the Startup
Folder.

On my machine I have Fedora Core 7 and Ubuntu 7.10 (Gutsy Gib). Now I
tried this on FC7 , worked perfectly.

Steps.

1. Open a terminal and login as root.

2. Now locate the file read by GNOME when it starts a default session.
The file is named as "default.session" and for me its path was
"/usr/share/gnome/default.session". If for you the file does not exist
there, you can look for the file by using the command
"find / -name default.session". The file will be stored under a
directory named gnome.

3. Once you get the file open it with a text editor.

4. It will be something like this:
------------------------------------------------------------------------------------------------------------------------
# This is the default session that is launched if the user doesn't
# already have a session.
# The RestartCommand specifies the command to run from the $PATH.
# The Priority determines the order in which the commands are started
# (with Priority = 0 first) and defaults to 50.
# The id provides a name that is unique within this file and passed to
the
# app as the client id which it must use to register with gnome-session.
# The clients must be numbered from 0 to the value of num_clients - 1.

[Default]
num_clients=6
0,id=default0
0,Priority=60
0,RestartCommand=pam-panel-icon --sm-client-id default0
1,id=default1
1,Priority=10
1,RestartCommand=gnome-wm --default-wm gnome-wm --sm-client-id default1
2,id=default2
2,Priority=40
2,RestartCommand=gnome-panel --sm-client-id default2
3,id=default3
3,Priority=40
3,RestartCommand=nautilus --no-default-window --sm-client-id default3
4,id=default4
4,Priority=40
4,RestartCommand=gnome-volume-manager --sm-client-id default4
5,id=default5
5,Priority=41
5,RestartCommand=evolution

------------------------------------------------------------------------------------------------------------------------
Now on everything is pretty simple. OK the entries.

num_clients=6 - It is the number of clients that would start once the
default session starts/

The numbers 0,1,2,3,4,5 are the application numbers. These along with
the id are used to mark an application.

Priority=[Num]. Each application has a different priority numbers which
states the criticality of the app. The point to be noted here is higher
the priority number is, the lesser critical the app is. In most systems
the highest priority is set to be 0 where as the minimum priority is 50.

e.g. I added evolution to startup. This was simple, I changed the
num_clients to 6 from 5, then added the last 3 lines to the file and
saved it. The next time I restarted GNOME, "Lo. Evolution was up :D"