Saturday, August 2, 2014

Automatic Email Files Downloader


This is a software i created because i wanted a way to download files for backup. This program makes it easy for you to download any files just by emailing the link to an email account. The program downloads the file whenever the computer is on and it happens in the background. In the middle of download if the computer is shut down then it resumes back when the computer is on. So, it is kinda like dropbox but the goal is download not upload. I have provided both the source and executable jar below. Please be advised that you need jre 1.7 or later installed on your computer to be able to run the executable jar file below.


AutomaticEmailFilesDownloader

AutomaticEmailFilesDownloaderSource





Friday, June 27, 2014

Line Shooter



Unfortunately i couldn't complete the tower defense game because the artist left in the middle of development. So, i have ended the project for now with a working simulation that shows enemy and player combat which i have uploaded. This is a new game i finished recently. I have always been a fan of vertical scrolling shooters. My motivation for this game came after this game

M.U.S.H.A


So, in the lack of art i used lines to create art for the units.

The game is available here. Also included in the link is a level editor. Please read the documentation to understand how to create levels for this game.

Line Shooter

Line Shooter Source



Sunday, May 4, 2014

Sunday, March 30, 2014

Marriage Card Game Update



The card game i was working on is complete. Because of issues related to java certification in browsers i have not uploaded it in the web so the game is available as a stand alone only at this point. Please let me know if you know the game and/or are interested in playing. The server is running on the cloud. Since the certificate is not cheap i don't know if i should buy the certificate or make it available as a stand alone. Anyways, I have really enjoyed working on this game over a period of about 3 months. There were many challenges but my passion for the game overcame all challenges one by one. At one point I had a terrible bug which crashed the whole system. If i hadn't created backup copies, which were duplicates all over the desktop, then i would have to suffer. I now understand the importance of a version control system so i will definitely be using a version control software for my future projects. The advantages i see of using a version control over just plain project in desktop is version control avoids duplicate copies of your project and secondly it is easy to revert back to earlier commits without the risk of crashing the whole project because of an obscure bug that you don't seem to find. Anyways, this was a happy end to a chapter, a game that i really enjoy playing. A new chapter has started.  I created an animated gif to show the operation of the game. For the complete rules of the game, please follow the link below.


http://www.pagat.com/rummy/marriage.html











Saturday, February 15, 2014

Matrix Search



Given a sorted row and column matrix, find if it contains an element?

#include <iostream>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <cassert>

using namespace std;

/*

1   2   3   4  
6   7   8   9
11 12 13 14
16 17 18 19


1   2        3   4  
6   7        8   9

11 12      13 14
16 17      18 19


We cut the matrix into 4 blocks at the center. We check the center element. If that is the element we are looking for, we return true else we do the same recursively in those 4 divided blocks. If the number is less than the top left most element in the block and greater than the right bottom most element in the block, we can return false since the element doesn't belong to the block.

*/

//My implementation
bool findElement(int ** nos, int r1, int c1, int r2, int c2, int no ){

    if(r1 > r2 ||c1 > c2) return false;
 
    if(no < nos[r1][c1] || no > nos[r2][c2]) return false;
 
    int mid_r = (r1+r2)/2;
    int mid_c = (c1+c2)/2;
   
    if(nos[mid_r][mid_c] == no) return true;
   
    return  findElement(nos, r1, c1, mid_r, mid_c, no) ||
            findElement(nos, r1, mid_c+1, mid_r, c2, no) ||
            findElement(nos, mid_r+1, c1, r2, mid_c, no) ||
            findElement(nos, mid_r, mid_c+1, r2, c2, no);
 
}


void sortRows(int ** nos, int row_size, int col_size){
    for(int i=0;i<row_size;i++){
            sort(nos[i], nos[i] + col_size);
    }
}

void sortCols(int ** nos, int row_size, int col_size){

    vector<int> list;
   
    for(int i=0;i<col_size;i++){
   
        for(int j=0;j<row_size;j++){
       
            list.push_back(nos[j][i]);
       
        }
        sort(list.begin(), list.end());
 
       for(int j=0;j<row_size;j++){
       
            nos[j][i] = list[j];
       
        }

        list.clear();
   
   
    }

}




class Array{

public:

int ** arr;
int row_size;
int col_size;

};



Array getARandomArray(int size_cap){

    int row_size = rand()%size_cap + 1;
    int col_size = rand()%size_cap + 1;


    int ** nos = new int*[row_size];
   
    for(int i=0;i<row_size;i++){
         nos[i] = new int[col_size];
    }
 
    Array toreturn;
    toreturn.arr = nos;
    toreturn.row_size = row_size;
    toreturn.col_size = col_size;
   
    return toreturn;

}




int main()
{
 
int value_range = 5000000;  //Value range of elements in the matrix
int total_tests = 100000;   // Total tests to be performed

int array_size_cap = 1000; // The generated array will have 1 <= row, col <= 1000


for(int t=0;t<total_tests;t++){

   
    Array tempa = getARandomArray(array_size_cap);
   
    int ** nos = tempa.arr;
    int row_size = tempa.row_size;
    int col_size = tempa.col_size;
   
   
    //Assign random values in value range
      for(int i=0;i<row_size;i++){
          for(int j=0;j<col_size;j++){
         
                nos[i][j] = rand()%value_range;
     
          }    
      }


    //pick a random element at random spot in the array
    int rand_item_row = rand() % row_size;
    int rand_item_col = rand() % col_size;
   


    //sort the array row and column wise
    sortRows(nos, row_size, col_size);
    sortCols(nos, row_size, col_size);
   
   
    //check if the algorithm finds that element
    assert(findElement(nos, 0, 0, row_size-1, col_size-1, nos[rand_item_row][rand_item_col]) == true);
     
   
    // free dynamically allocated memory
    for( int i = 0 ; i < row_size ; i++ )
    {
        delete[] nos[i]; // delete array within matrix
    }
   
    // delete actual matrix
    delete[] nos;


}


cout << "All tests passed ... "  << endl;
 
   
   return 0;
}

Saturday, February 8, 2014

Sudoku Solver





#include <iostream>

using namespace std;


bool isValid(char arr[][9]){
    
    //checking if each row has unique elements
   
    for(int i=0;i<9;i++){
        
          int temp[9] = {0};
          
         for(int j=0;j<9;j++){
        
            if(arr[i][j] != 0)
               temp[arr[i][j]-1]++;
            
        }
        
        for(int k=0;k<9;k++){
        
            if(temp[k] > 1) return false;
        
        }
        
    
    }
    
    
    //checking if each column has unique elements
    
    
    for(int i=0;i<9;i++){
    
        int temp[9] = {0};
                
        for(int j=0;j<9;j++){
        
            if(arr[j][i] != 0)
                temp[arr[j][i]-1]++;
            
        }
        
        for(int k=0;k<9;k++){
        
            if(temp[k] > 1) return false;
        
        }
    
    
    }
    
    
    
    //checking if each 3x3 have unique elements
    
    
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
                
            int temp[9] = {0};
                
            for(int k=i*3;k<(i*3+3);k++){
            
                for(int l=j*3;l<(j*3+3);l++){
                
                    if(arr[k][l] != 0)
                        temp[arr[k][l]]++;            
                
                }          
            
            }
                
            for(int k=0;k<9;k++){
        
                if(temp[k] > 1) return false;
            
            }
        
        
        }
    }
    
    return true;  

}



bool isSolved(char arr[][9]){

    for(int i=0;i<9;i++){
    
        for(int j=0;j<9;j++){
        
            if(arr[i][j] == 0) return false;
        
        }
        
    }
    
    return isValid(arr);


}




int values_tried = 0;
bool solved = false;


void solveSudoku(char arr[][9]){


    if(!isValid(arr)) return;

    if(isSolved(arr)){
    
        for(int i=0;i<9;i++){
           for(int j=0;j<9;j++){
               cout << (int)arr[i][j] << "  ";
            
            }
           cout << endl;
       }
  
        cout << "This many values tried " << values_tried << endl; 
        
        solved = true;
        
        return;
    
    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////TRY 1-9 VALUES FOR EACH CELL AND CHECK FOR VALIDITY RECURSIVELY/////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    for(int i=0;i<9;i++){    
        for(int j=0;j<9;j++){
               
            if(arr[i][j] == 0){
        
                //Trying all values 1-9 for each cell
                for(int k=1;k<=9;k++){
                        
                    values_tried++;
                    arr[i][j] = k;
                    
                    solveSudoku(arr);
                    
                    arr[i][j] = 0;
                
                }
                
                //1-9  didnt work so backing out  
                return;
            
            }
       
            if(solved) break;          
       
        }

        if(solved) break;

    }
}





int main()
{


char arr[9][9] = {

{8, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 3, 6, 0, 0, 0, 0, 0},
{0, 7, 0, 0, 9, 0, 2, 0, 0},
{0, 5, 0, 0, 0, 7, 0, 0, 0},
{0, 0, 0, 0, 4, 5, 7, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 3, 0},
{0, 0, 1, 0, 0, 0, 0, 6, 8},
{0, 0, 8, 5, 0, 0, 0, 1, 0},
{0, 9, 0, 0, 0, 0, 4, 0, 0}

};


solveSudoku(arr);
cout << "Done" << endl;
return 0;
}





Output:


Saturday, February 1, 2014

8 - Puzzle


As a kid, i remember playing a variation of this puzzle. The only difference was instead of numbers the game had a picture. After scrambling the picture the goal was to reconstruct the initial picture. I was very much fond of the game as a kid. I dont know why but maybe the picture was something that made the game interesting. Today i wrote a program to calculate total arrangements possible from the given initial configuration.


If you do not know the rule, the idea is to reach one configuration from the given initial configuration. The only rule is you can slide the tile to empty spot. You cannot jump. The tile that is free can only move.



If the initial configuration is the following. 


We can slide tile 6 down which gives the following configuration.


Similarly we can slide tile 5 right which gives the following. I hope you have a good idea by now.


So, given an initial configuration, the goal is to reach the given goal configuration.


Today i was playing around with this puzzle and wanted to check how many ways there are actually from this initial configuration.


The answer i got was 181440. Holy crap! It didn't seem like this simple looking puzzle would yield that many unique configurations.


Following is the code I wrote to generate the total unique configurations from the above configuration. Since there were a finite number of things to keep track of in a given state, i used an int to pack the state that way i can save space and time. So, instead of passing 3x3 array around, i can just pass the integer. Another positive thing from this was since primitives are passed by value, i didn't need to worry about duplicating the state. It is automatically duplicated when passed into a function.


#include <iostream> #include <vector> #include <algorithm> #include <map> using namespace std; map<int, int> mp; /* 1 2 3 4 5 6 7 8 __ __ __ __ __ __ __ __ I divide the integer into 8 parts. each part or a nibble will hold x and y of number corresponding to the position for example: the following holds x, y of 1 which is 0 because x = 0, y = 0 __ __ __ __ __ __ __ 0x0 the following holds x, y as 2 because x = 1, y = 0 0x10 = 2 __ __ __ __ __ __ 0x10 __ */ unsigned int pack(int temp[][3]){ unsigned int r = 0; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ if(temp[i][j] == 0) continue; int tt = temp[i][j]; unsigned int nib = (j<<2) | i; nib <<= (tt-1)*4; r |= nib; } } return r; } /* Just like pack converts the 3x3 array to a integer. This does the reverse. */ void unpack(unsigned int n, int temp[][3]){ int num = 1; while(num <= 8){ int xy = n & 0xf; int y = xy&0x3; int x = (xy>>2)&0x3; temp[y][x] = num; num++; n >>= 4; } } /* This function is used to move the tile and return the packed form of the resultant array example: temp 1 2 3 4 5 6 7 8 from_i = 2, from_j = 2 to_i = 1, to_j = 2 then temp 1 2 3 4 5 7 8 6 */ unsigned int packArray(int temp[][3], int from_i, int from_j, int to_i, int to_j){ int temp2[3][3] = {0}; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ temp2[i][j] = temp[i][j]; } } int t = temp2[from_i][from_j]; temp2[from_i][from_j] = temp2[to_i][to_j]; temp2[to_i][to_j] = t; return pack(temp2); } /* Computes the total unique arrangements starting at configuration n */ void totalArrangements(unsigned int n){ //check if this state is already recorded if (mp[n] != 0) return; //if no, record it mp[n]++; //Convert the integer state to array by unpacking int temp[3][3] = {0}; unpack(n, temp); int index_i = -1; int index_j = -1; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ if(temp[i][j] == 0) { index_i = i; index_j = j; break; } } if(index_i != -1 && index_j != -1) break; } /* There are 4 possible ways to move the empty slot. */ //RIGHT if((index_i+1) <= 2){ int n = packArray(temp, index_i, index_j, index_i+1, index_j); totalArrangements(n); } //LEFT if((index_i-1) >= 0){ int n = packArray(temp, index_i, index_j, index_i-1, index_j); totalArrangements(n); } //DOWN if((index_j+1) <= 2){ int n = packArray(temp, index_i, index_j, index_i, index_j+1); totalArrangements(n); } //UP if((index_j-1) >= 0){ int n = packArray(temp, index_i, index_j, index_i, index_j-1); totalArrangements(n); } } int main() { //8 puzzle /* 1 2 3 4 5 6 7 8 X */ int nomatch_count = 0; vector<int> list; list.push_back(1); list.push_back(2); list.push_back(3); list.push_back(4); list.push_back(5); list.push_back(6); list.push_back(7); list.push_back(8); list.push_back(0); int temp[3][3] = {0}; for(int i=0;i<list.size();i++){ temp[i/3][i%3] = list[i]; } totalArrangements(pack(temp)); cout << "Total reachable were " << mp.size() << endl; return 0; }





I noticed that the output was 181440. I calculated the total possible permutations of the puzzle which was 9! = 362880. 181440 was in fact half of 362880. This was little surprising. This means about half of the total permutations were reachable from the above configuration. I also printed out the total configurations that weren't reachable by adding the following code.



   for(int i=0;i<9;i++) {    
       for(int j=0;j<9;j++){    
            if(j == i) continue;    
           for(int k=0;k<9;k++){            
               if(k == i || k == j) continue;
                for(int l=0;l<9;l++){                  
                    if(l == i || l == j || l == k) continue;                
                    for(int m=0;m<9;m++){                      
                        if(m == i || m == j || m == k || m == l) continue;
                        for(int n=0;n<9;n++){
                            if(n == i || n == j || n == k || n == l || n == m) continue;
                            for(int o=0;o<9;o++){
                                if(o == i || o == j || o == k || o == l || o == m || o == n) continue;
                                for(int p=0;p<9;p++){
                                    if(p == i || p == j || p == k || p == l || p == m || p == n || p == o) continue;
                                    for(int q=0;q<9;q++){
                                        if(q == i || q == j || q==k || q==l || q==m || q==n || q == o || q == p) continue;
                                 
 //Test this configuration
temp[0][0] = list[i];
temp[0][1] = list[j];
temp[0][2] = list[k];

temp[1][0] = list[l];
temp[1][1] = list[m];
temp[1][2] = list[n];

temp[2][0] = list[o];
temp[2][1] = list[p];
temp[2][2] = list[q];
                             

unsigned int t =  pack(temp);


int temp1[3][3] = {0};

unpack(t, temp1);


if(mp.find(t) == mp.end()){

                  nomatch_count++;

}


                                    }
                                    }}}}}}}}
 






cout << "Total non reachable were " << nomatch_count << endl;



Output of the program was

Total reachable were 181440
Total non reachable were 181440

This was an interesting find out. The states are divided into two islands. One island has states that are unreachable from any state from another island.

Following are few of the unreachable states form the following configuration as reported by the program.

Following are unreachable.




Thursday, January 23, 2014

Find the longest path between any two nodes in a binary tree


Following is the test i created for my implementation of the above problem.


#include <iostream> #include <algorithm> #include <stdlib.h> #include <vector> #include <sys/time.h> using namespace std; class Node{ public: Node * left; Node * right; int val; Node(int v){ left = NULL; right = NULL; val = v; } }; void traverseAndAdd(Node * n, vector<Node *> * nodes){ if(n == NULL) return; nodes->push_back(n); traverseAndAdd(n->left, nodes); traverseAndAdd(n->right, nodes); } //someone else's implementation..assumed correct int diameterOpt(Node * n, int * height){ int lh, rh = 0; if(n == NULL){ *height = 0; return 0; } int left_diameter = diameterOpt(n->left, &lh); int right_diameter = diameterOpt(n->right, &rh); *height = max(lh, rh) + 1; return max(lh + rh + 1, max(left_diameter, right_diameter)); } int heightOf(Node * n){ if(n == NULL) return 0; return 1 + max(heightOf(n->left), heightOf(n->right)); } int max_length = -1; //my implementation void maxPathLength(Node * n){ if(n == NULL) return; int left_height = heightOf(n->left); int right_height = heightOf(n->right); if((left_height + right_height + 1) > max_length) max_length = left_height + right_height + 1; if(left_height >= right_height){ maxPathLength(n->left); } else { maxPathLength(n->right); } } double getTime() { struct timeval tp; gettimeofday(&tp, NULL); return ((double) tp.tv_sec + (double) tp.tv_usec * 1e-6); } int main() { double starttime = getTime(); for(int k=0;k<20000;k++){ vector<int> nos; int length = k+1; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////CREATE A BINARY TREE WITH k NODES/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// for(int i=1;i<=length;i++) nos.push_back(i); int len = nos.size(); vector<Node *> nodes; for(int i=0;i<len;i++){ nodes.push_back(new Node(nos[i])); } for(int i=1;i<=(len/2);i++){ nodes[i-1]->left = nodes[2*i - 1]; nodes[i-1]->right = nodes[2*i]; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////KEEP CUTTING RANDOM BRANCH TILL THE TREE HAS JUST THE ROOT NODE///////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// while(nodes.size() != 1){ int index_to_delete = rand() % nodes.size(); int ri = rand()%2; //////HERE WE CUT EITHER LEFT OR RIGHT BRANCH RANDOMLY if(ri == 0){ nodes[index_to_delete]->left = NULL; } else { nodes[index_to_delete]->right = NULL; } Node * temp = nodes[0]; int height = 0; maxPathLength(temp); //MY IMPLEMENTATION ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////NOW COMPARING THE OUTPUT OF MY IMPLEMENTATION WITH THE OUTPUT OF THE CORRECT SOLUTION//////////////////////////// ////////////////////////////////////////(diameterOpt is correct implementation)////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //CHECKING MY IMPLEMENTATION WITH if( max_length != diameterOpt(temp, &height)){ cout << "Failed ..." << endl; } max_length = -1; nodes.clear(); //THIS UPDATES THE TREE WITH CUT BRANCH TAKEN OUT traverseAndAdd(nodes[0], &nodes); } } cout << endl; cout << "Total time taken was " << getTime() - starttime << endl; cout << "Done" << endl; return 0; }


The output of the program was

Total time taken was 18350 Done

It was a relief to see no "Failed ...". Though not a guarantee it gives more credence to the implementation.