Saturday, October 20, 2012

Longest Palindromic Subsequence or Maximum Length of Palindrome

Definition:
              A sequence is called "Palindrome" if it is read same left to right and right to left. The sequence remains same as before after reversing it. The sequence "MADAM" is a Palindrome.
More about Palindrome.

A sequence which is a Palindrome is called a Palindromic Sequence. In this problem, given any sequence (not necessarily palindromic sequence), and we have to determine the Longest Palindromic Sub-sequence of Maximum Length of Palindrome of it.
A dynamic approach is not mandatory for this problem, because there is no overlapping sub-problems and so no optimal sub-structure available for Longest Palindromic Sub-sequence.
But if we go recursively, it can be easily determined. How? Obviously there is no overlapping sub-problems but we can divide it into sub-problems (that how we do it :p).
Here is a C++ solution for LPS.


#include <iostream>
#include <string>

using namespace std;

template<class T>inline T MAX( T a, T b ){ return a>b ? a:b; } // Note: returns maximum of a and b

string A;

int LPS( int i, int j ) {
    if( i == j ) return 1; // A[i] & A[j] are same, cost is 1
    if( i > j ) return 0;
    if( A[i] == A[j] )
        return 2 + LPS( i+1, j-1 ); // A[i] & A[j] are different, cost is 2, 1 for each.
    else
        return MAX( LPS(i+1, j), LPS(i, j-1) );
}

int main( ){
    while( cin >> A ){
        int len = A.length( );
        int res = LPS(0, len);
        cout << "Longest Palindromic Subsequence is: " << res << endl;
    }
    return 0;
}

Obviously, a memoization make the procedure lot more faster. Here is a memoized faster version.

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

template<class T>inline T MAX( T a, T b ){ return a>b ? a:b; } // Note: returns maximum of a and b
const int SIZ = 105;

#define mset2d(x,n) memset(x,n,sizeof(int [SIZ][SIZ]))

string A;
int memo[SIZ][SIZ];

int LPS( int i, int j ) {
    if( i == j ) return 1; // A[i] & A[j] are same, cost is 1
    if( i > j ) return 0;
    if( memo[i][j] != -1 ) return memo[i][j];
    if( A[i] == A[j] )
        memo[i][j] = 2 + LPS( i+1, j-1 ); // A[i] & A[j] are different, cost is 2, 1 for each.
    else
        memo[i][j] = MAX( LPS(i+1, j), LPS(i, j-1) );
    return memo[i][j];
}

int main( ){
    while( cin >> A ){
        mset2d( memo, -1 );
        int len = A.length( );
        int res = LPS(0, len);
        cout << "Longest Palindromic Subsequence is: " << res << endl;
    }
    return 0;
}

Monday, October 15, 2012

Addition, Subtraction & Multiplication in .ASM

Addition, Subtraction & Multiplication of two numbers submitted, until the program terminates by user. The termination process is actually maintained by 0 and 1, 0 terminates the program and 1 continues.
Limitations of the code is the initial two numbers and the resultant numbers must be between 0 to 9. "emu8086" compiler was used. This is my 5th code in assembly language I have done in my lab.
; Date: October 10, 2012
; Author: Md. Nabid Imteaj
; Tag: Add, Substract, Multiplication as user want

TITLE ANOTHER_DAY_IN_CLASS  
.model small
.stack 100h
.code

.data
msg1 db 'ENTER Hex Value: $'
msg2 db 'Equivalent Decimal: $' 
msg3 db 'INVALID :($'
msg10 db '0 to exit, 1 to continue?: $'
msg11 db 'THANK YOU :D$' 

main proc
    
    mov ax, @data
    mov ds, ax 
    
    mov cx, 3

AGAIN_PAIN: 
; new line
    mov ah, 2
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h 

cmp cl, 0
je TERMINATE
dec cx

; message print

    lea dx, msg1
    mov ah, 9
    int 21h
    
; enter character
    mov ah, 1
    int 21h 
    mov bl, al
    
    ; new line
    mov ah, 2
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h
    
; cmpareing
    cmp bl, 'A'
    je print_A
    cmp bl, 'B'
    je print_B 
    cmp bl, 'C'
    je print_C
    cmp bl, 'D'
    je print_D
    cmp bl, 'E'
    je print_E
    cmp bl, 'F'
    je print_F 
    
    cmp bl, 30
    jge over_0
    
over_0:
    cmp bl, 39
    jle less_9 
    jmp print_invalid

less_9:
    mov ah, 2
    mov dl, bl
    int 21h 
    jmp EXIT_ 
    
print_A:  
lea dx, msg2
mov ah, 9
int 21h
   
    mov ah, 2
    mov dl, '1'
    int 21h
    mov ah, 2
    mov dl, '0'
    int 21h 
    jmp EXIT_ 
    
print_B:
lea dx, msg2
mov ah, 9
int 21h 
    mov ah, 2
    mov dl, '1'
    int 21h
    mov ah, 2
    mov dl, '1'
    int 21h 
    jmp EXIT_
    
print_C:
lea dx, msg2
mov ah, 9
int 21h 
    mov ah, 2
    mov dl, '1'
    int 21h 
    mov ah, 2
    mov dl, '2'
    int 21h 
    jmp EXIT_
    
print_D:
lea dx, msg2
mov ah, 9
int 21h 
    mov ah, 2
    mov dl, '1'
    int 21h 
    mov ah, 2
    mov dl, '3'
    int 21h 
    jmp EXIT_
    
print_E:
lea dx, msg2
mov ah, 9
int 21h 
    mov ah, 2
    mov dl, '1'
    int 21h
    mov ah, 2
    mov dl, '4'
    int 21h  
    jmp EXIT_     
    
print_F:
lea dx, msg2
mov ah, 9
int 21h 
    mov ah, 2
    mov dl, '1'
    int 21h
    mov ah, 2
    mov dl, '5'
    int 21h  
    jmp EXIT_ 
           
print_invalid:
    lea dx, msg3
    mov ah, 9
    int 21h
    jmp EXIT_
               
  
EXIT_: 

; new line
    mov ah, 2
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h    
    
; operation message
    lea dx, msg10
    mov ah, 9
    int 21h 
    
; gets character
    mov bl, '1'
    mov ah, 1
    int 21h
    
    cmp al, bl
    je AGAIN_PAIN
    
    ; new line
    mov ah, 2
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h 
    
TERMINATE:   
     ; operation message
    lea dx, msg11
    mov ah, 9
    int 21h 

mov ah, 4ch
int 21h
main endp
end main

Sunday, September 23, 2012

Maximum Interval Sum


Given a array of natural numbers, we have to find the maximum interval sum.
5    5   -1    5    5
Now we have these intervals (5 + 5), ( 5 + 5 + (-1)), (5 + 5 + (-1) + 5), (5 + 5 + (-1) + 5 + 5). 
Which interval has maximum sum?
(5 + 5) = 10
( 5 + 5 + (-1)) = 9
(5 + 5 + (-1) + 5) = 14
(5 + 5 + (-1) + 5 + 5) = 19
So, the last interval has maximum sum. These type of problems are called Maximum Interval Sum.
C++ implementation:

#include <iostream>
using namespace std;
const int INF = (-(1<<30));  // negative infinity
int MIS( ) {
    sum = 0; // initially sum is 0
    Max = -INF; // Maximum is less than 0
    for( i=0; i<N; i++ ) {
       sum += A[i]; // "A[]" array of intejars
        if( sum > Max ) Max = sum;
        if( sum < 0 ) sum = 0;  // sum below 0 is not useful, right?
    }
    return Max;
}

Wednesday, September 19, 2012

Message Print in Assembly Language

TITLE PRINTING HABIJABI

.MODEL SMALL    

.STACK 100H   

.DATA
MSG  DB 'Take Input: $'
MSG1 DB 'First Value: $'
MSG2 DB 'Second Value: $'
A    DB 5
B    DB ?

MAIN PROC
; initializing data segment  
    MOV AX, @DATA
    MOV DS, AX  ; initialized :D 
    
; display message
    LEA DX, MSG
    MOV AH, 9  ; message print function
    INT 21h  
    
; input 
    MOV AH, 1
    INT 21h
    MOV B, AL
    
; new line
    MOV AH, 2
    MOV DL, 0DH
    INT 21H
    MOV DL, 0AH
    INT 21H   
    
; display message1
    LEA DX, MSG1
    MOV AH, 9  ; message print function
    INT 21h
    
; display A
    MOV AH, 2
    MOV DL, A
    INT 21h
    
; new line
    MOV AH, 2
    MOV DL, 0DH
    INT 21H
    MOV DL, 0AH
    INT 21H   
    
; display message2
    LEA DX, MSG2
    MOV AH, 9  ; message print function
    INT 21h
    
; display B 
    MOV AH, 2
    MOV DL, B
    INT 21h
    
; return to DOS

    MOV AH, 4CH
    INT 21h
    
MAIN ENDP
    END MAIN

Maximum Sum Sub Matrix


Problem:

        Given m*n matrix. We have to find a sub-matrix which have maximum sum. Values of the matrix can be both positive and negative.

Idea:

      Lets start with an example then we will generate our idea. Suppose we have 4*4 matrix as below:
    [ initial matrix ] 
-1      2     3      10          
 5      9    -7       6
 0    -1     -3     -5
 7     5   -18       2
Now we add first column with second column. So, the matrix became like this:
-1      1     3      10
 5     14    -7       6
 0    -1     -3     -5
 7    12   -18       2
Now add second column with third column and the third column with last column. Then, the matrix will look like:
-1      1     4      14
 5     14     7      13
 0    -1     -4      -9
 7    12    -6      -4

Now the row addition part. Add first row with second, then add second with third, then third with last. Finally, the matrix will be:
-1      1      4      14
 5     15    11     27
 0     14     7      18
 7     26     1      14

Our matrix is ready to manipulate.

-1
1
4
14
4
15
11
27
4
14
7
18
11
26
1
14
Definitely, we can say form this matrix that value of every cell is the sum of (0,0) to that cell. Say, (1,1) is 15 is the sum of (0,0), (0,1), (1,0) and (1,1) cells that is 15 i.e. ( -1+2+5+9 ) = 15. This property makes our idea easier. 
       In this matrix, the maximum sum is the middle sub-matrix. ( 15 + 11 + 14 + 7 ) = 37.
-1
1
4
14
4
15
11
27
4
14
7
18
11
26
1
14
We are very closer to our solution. Now, see carefully. Cell (2,2) has cumulative sum form cell (0,0) to (2,2).  
-1
1
4
14
4
15
11
27
4
14
7
18
11
26
1
14
We can subtract the sum of cell (0,0) to (0,2) from this result. 
-1
1
4
14
4
15
11
27
4
14
7
18
11
26
1
14
Again, we subtract sum of cell (0,0) to (2, 0) from the last result.
-1
1
4
14
4
15
11
27
4
14
7
18
11
26
1
14
Have we finished ? No. Look at the matrix above carefully. We have subtract cell (0,0) from the actual result  twice. It should be once. Finally, add the (0,0) cell to actual result and we get our maximum sum sub-matrix.
Thanks - Jajabor, 2014