Sunday, April 17, 2016

Trie Data Structure

A trie (or a prefix tree) is a data structure similar to n-ary trees, where each node can have n children. Each child holds a reference to the next n children.

Here an example trie is discussed where some words are stored in the trie.

The TrieNode consists of the following elements:

class TrieNode {
    boolean isWord = false;
    TrieNode[] children = new TrieNode[26];
}

Here each node can have 26 children. Some children may point to null and others may point to the next character in the word.

For example, when the words "home" and "hot" are added to the trie, the state of the trie can be described as follows:
1. The first level will hold 26 children with only the 8th ("h") child holding a non-null reference. Rest of the 25 children will be null.
2. The second level which is the children of "h" will hold 25 null children with only the 15th ("o") child holding a non-null reference.
3. The third level will which is the children of "o" will hold 2 non-null references ("m" and "t") and rest 24 children will be null.
4. The fourth level will have one non-null reference ("e"), which is one of the children of "m", and "t" will hold 26 null references.

Java Code:

package com.sourabh.third;

import java.util.LinkedList;
import java.util.Queue;

class TrieNode {
 boolean isWord = false;
 TrieNode[] children = new TrieNode[26];
 public TrieNode() {
  
 }
 
 public TrieNode(String key) {
  this.add(key);
 }
 
 public boolean contains(String in) {
  TrieNode node = this;
  for(int i=0; i<in.length();i++) {
   TrieNode child = node.children[getAscii(in.charAt(i))];
   if(child == null) {
    // This particular character is not present in the current branch.
    return false;
   }
   else {
    if(in.length() - 1 == i) {
     // We have reached the end of the input string.
     return true;
    }
    else {
     node = child;
    }
   }
  }
  return false;
 }
 
 public void add(String in) {
  if(in.length() == 0) {
   this.isWord = true;
   return;
  }
  else {
   char first = in.charAt(0);
   TrieNode child = children[getAscii(first)];
   if(child == null) {
    child = new TrieNode();
    children[getAscii(first)] = child;
   }
   child.add(in.substring(1));
  }
 }
 
 public int getAscii(char c) {
  char A[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  int i=0;
  for(i=0;i<A.length;i++) {
   if(A[i] == c) {
    break;
   }
  }
  return i;
 }
}

public class TriePrograms {
 public TrieNode createNode(String word) {
  if(word == null) {
   return new TrieNode();
  }
  else {
   return new TrieNode(word);
  }
 }
 
 public void levelOrderTraversal(TrieNode node) {
  Queue<TrieNode[]> queue = new LinkedList<>();
  if(node == null) {
   return;
  }
  queue.add(node.children);
  int thisLevel = 1;
  int nextLevel = 0;
  while(!queue.isEmpty()) {
   for(int ele = 0; ele < thisLevel; ele++) {
    TrieNode[] childrenAtThisLevel = queue.remove();
    for(int i=0; i<childrenAtThisLevel.length; i++) {
     if(childrenAtThisLevel[i] != null) {
      System.out.print(getChar(i) + ".");
      queue.add(childrenAtThisLevel[i].children);
      nextLevel++;
     }
     else {
      System.out.print(".");
     }
    }
   }
   thisLevel = nextLevel;
   System.out.println();
   for(int i=0;i<26;i++) {
    System.out.print("-");
   }
   System.out.println();
   for(int i=0;i<26;i++) {
    System.out.print("|");
   }
   System.out.println();
   nextLevel = 0;
  }
  thisLevel = nextLevel;
 }
 
 public char getChar(int ascii) {
  char A[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  return A[ascii];
 }
}

Unit Tests:

package com.sourabh.third;

import org.junit.Assert;
import org.junit.Test;

public class TrieProgramTests {

 TriePrograms instance = new TriePrograms();
 
 @Test
 public void testContains() {
  TrieNode node = instance.createNode(null);
  node.add("home");
  Assert.assertTrue(node.contains("home"));
  node.add("house");
  Assert.assertTrue(node.contains("house"));
  node.add("hot");
  Assert.assertTrue(node.contains("hot"));
  Assert.assertFalse(node.contains("hole"));
 }
 
 @Test
 public void testConstructor() {
  TrieNode node = instance.createNode("home");
  Assert.assertTrue(node.contains("home"));
  node.add("house");
  Assert.assertTrue(node.contains("house"));
  node.add("hot");
  Assert.assertTrue(node.contains("hot"));
  Assert.assertFalse(node.contains("hole"));
 }
 
 @Test
 public void testLevelOrderTraversal() {
  TrieNode node = instance.createNode("home");
  node.add("house");
  node.add("hot");
  instance.levelOrderTraversal(node);
 }
}

Trie printed in level order:
.......h...................
--------------------------
||||||||||||||||||||||||||
..............o............
--------------------------
||||||||||||||||||||||||||
............m.......t.u......
--------------------------
||||||||||||||||||||||||||
....e..................................................................s........
--------------------------
||||||||||||||||||||||||||
..............................e......................
--------------------------
||||||||||||||||||||||||||
..........................
--------------------------
||||||||||||||||||||||||||

Sunday, April 3, 2016

Find the smallest window within an array that contains all the elements of another array

Java Program:

package com.sourabh.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class MinimumArrayContains {
 class Interval
 {
  private int start;
  private int end;
  public Interval()
  {
   super();
  }
  public Interval(int start, int end) {
   super();
   this.start = start;
   this.end = end;
  }
  public int getStart() {
   return start;
  }
  public void setStart(int start) {
   this.start = start;
  }
  public int getEnd() {
   return end;
  }
  public void setEnd(int end) {
   this.end = end;
  }
 }
 
 Map<Integer, Boolean> map = new HashMap<>();
 Queue<Integer> queue = new LinkedList<>();
 public void resetMap(int... A) {
  for(int i=0;i<A.length;i++) {
   map.put(A[i], false);
  }
 }
 
 public Interval resetQueue() {
  int start = queue.peek();
  int end = 0;
  while(!queue.isEmpty()) {
   end = queue.remove();
  }
  return new Interval(start, end);
 }
 
 public List<Interval> getIntervals(int[] A1, int[] A2) {
  int found = 0;
  int end = 0;
  List<Interval> intervalsContainingAllElementsOfA2 = new ArrayList<>();
  resetMap(A2);
  for(int i=0; i<A1.length; i++) {
   if(map.containsKey(A1[i])) {
    if(map.get(A1[i]) == false) {
     found++;
     map.put(A1[i], true);
    }
    if(queue.peek()!= null && A1[i] == A1[queue.peek()]) {
     queue.remove();
    }
    queue.add(i);
    end = i;
   }
   if(found == A2.length) {
    int start = queue.peek();
    intervalsContainingAllElementsOfA2.add(new Interval(start, end));
    int prevIndex = queue.remove();
    map.put(A1[prevIndex], false);
    found--;
    int currIndex = queue.remove();
    map.put(A1[currIndex], false);
    found--;
    while(currIndex - prevIndex ==1) {
     prevIndex = currIndex;
     currIndex = queue.remove();
     found--;
     map.put(A1[currIndex], false);
    }
    i = currIndex;
    queue.add(currIndex);
    map.put(A1[currIndex], true);
    found++;
   }
  }
  return intervalsContainingAllElementsOfA2;
 }
 
 public Interval getMinimumInterval(int[] A1, int[] A2) {
  List<Interval> intervalsList = getIntervals(A1, A2);
  Interval minInterval = intervalsList.get(0);
  for(Interval interval : intervalsList) {
   if(interval.getEnd() - interval.getStart() < minInterval.getEnd() - minInterval.getStart()) {
    minInterval = interval;
   }
  }
  return minInterval;
 }
}

Unit Tests:
package com.sourabh.test;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.junit.Test;
import org.junit.Assert;
import com.sourabh.test.MinimumArrayContains.Interval;

public class QueueTest {

 Queue<Integer> queue = new LinkedList<>();
 MinimumArrayContains instance = new MinimumArrayContains();
 
 @Test
 public void testQueueFunctions() {
  queue.add(1);
  queue.add(2);
  queue.add(3);
  queue.add(4);
  Assert.assertTrue(queue.peek() == 1);
  Assert.assertTrue(queue.remove() == 1);
  Assert.assertTrue(queue.peek() == 2);
  Assert.assertTrue(queue.remove() == 2);
 }
 
 @Test
 public void testGetMinInterval1() {
  int[] A1 = {1,2,3,1,2,1,4,6,5,4,2,3,4,1};
  int[] A2 = {1,2,4,5};
  Interval interval = instance.getMinimumInterval(A1, A2);
  Assert.assertEquals(4, interval.getStart());
  Assert.assertEquals(8, interval.getEnd());
 }
 
 @Test
 public void testGetMinInterval2() {
  int[] A1 = {6, 7, 1, 3, 2, 4, 5, 2, 3, 1, 2, 5};
  int[] A2 = {1, 3, 5};
  Interval interval = instance.getMinimumInterval(A1, A2);
  Assert.assertEquals(3, interval.getEnd() - interval.getStart());
 }
}

Water in valley one dimensional


Problem:
Given a one dimensional array of integers representing the height of cliffs of a valley, find the total amount of water that can be filled in the valley.

Diagram:


Java Program:

package com.sourabh.test;

import java.util.ArrayList;
import java.util.List;

public class ValleyWater {
 class Valley
 {
  private int start;
  private int end;
  private int water;

  public Valley() {
   super();
  }
  public Valley(int start, int end) {
   super();
   this.start = start;
   this.end = end;
  }
  public int getStart() {
   return start;
  }
  public void setStart(int start) {
   this.start = start;
  }
  public int getEnd() {
   return end;
  }
  public void setEnd(int end) {
   this.end = end;
  }
  public int getWater() {
   return water;
  }
  public void setWater(int water) {
   this.water = water;
  }
 }
 
 public List<Valley> getValleys(int... A) {
  List<Integer> maxima = new ArrayList<>();
  List<Integer> minima = new ArrayList<>();
  List<Valley> valleysList = new ArrayList<>();
  int index = 0;
  for(int i=0;i<A.length - 1;i++) {
   if(A[i+1] > A[i]) {
    minima.add(i);
    index = i;
    break;
   }
   if(A[i+1] < A[i]) {
    maxima.add(i);
    index = i;
    break;
   }
  }
  for(int i=index+1;i+1<A.length;i++) {
   if(A[i+1] < A[i] && A[i] >= A[i-1]) {
    maxima.add(i);
   }
   if(A[i+1] > A[i] && A[i] <= A[i-1]) {
    minima.add(i);
   }
  }
  for(int i = 0; i < maxima.size() - 1; i++) {
   valleysList.add(new Valley(maxima.get(i), maxima.get(i+1)));
  }
  return valleysList;
 }
 
 public int addWater(List<Valley> valleysList, int... A) {
  int totalWater = 0;
  for(Valley valley : valleysList) {
   int min = A[valley.getStart()] < A[valley.getEnd()] ? A[valley.getStart()] : A[valley.getEnd()];
   int water = 0;
   for(int i=valley.getStart(); i<=valley.getEnd(); i++) {
    if(A[i] < min) {
     water += min - A[i];
    }
   }
   valley.setWater(water);
   totalWater += water;
  }
  for(Valley valley : valleysList) {
   System.out.println(valley.getWater());
  }
  return totalWater;
 }
 
 public int getWater(int... A) {
  return addWater(getValleys(A), A);
 }
}
Unit Tests:
package com.sourabh.test;

import static org.junit.Assert.*;

import java.util.List;
import com.sourabh.test.ValleyWater.Valley;
import org.junit.Assert;

import org.junit.Test;

public class ValleyWaterTests {

 ValleyWater instance = new ValleyWater();
 
 @Test
 public void getValleysTest() {
  int[] A = {1,2,3,1,2,1,4,6,5,4,2,3,4,1};
  List<Valley> valleysList = instance.getValleys(A);
  Assert.assertEquals(3, valleysList.size());
  Assert.assertEquals(2,valleysList.get(0).getStart());
  Assert.assertEquals(4,valleysList.get(0).getEnd());
  Assert.assertEquals(4,valleysList.get(1).getStart());
  Assert.assertEquals(7,valleysList.get(1).getEnd());
  Assert.assertEquals(7,valleysList.get(2).getStart());
  Assert.assertEquals(12,valleysList.get(2).getEnd());
 }
 
 @Test
 public void getWaterTest() {
  int[] A = {1,2,3,1,2,1,4,6,5,4,2,3,4,1};
  int totalWater = instance.getWater(A);
  Assert.assertEquals(5, totalWater);
 }
}

Thursday, March 31, 2016

Friction on Inclined Plane

Collision

Elastic Collision

A collision of masses where both momentum and energy of the system is conserved before and after the collision.
Conservation of Momentum:
m1u1 + m2u2 = m1v1 + m2v2

Conservaation of Energy:
m1u12 + m2u22 = m1v12 + m2v22



Inelastic Collision

A collision of masses where only momentum of the system is conserved before and after the collision.
Conservation of Momentum:
m1u1 + m2u2 = m1v1 + m2v2

Sunday, February 21, 2016

Given a string with I and D output a sequence of numbers

Problem:
Given a string with "I" and "D" where "I" stands for Increment and "D" stands for Decrement, produce a sequence of numbers which follows the same pattern as the input string.

Sample Input:
ID
IID
IDDI

Sample Output:
2 3 1
2 3 4 1
3 4 2 1 5

C++ Program:
 
#include <iostream>
using namespace std;

void printNumbers(string input) {
    if (input.length() == 0) {
        return;
    }
    int dCount = 0;
    for (int i = 0; i < input.length(); i++) {
        if (input[i] == 'D') {
            dCount++;
        }
    }
    int numbers[100];
    for (int i = 0; i <= input.length(); i++) {
        numbers[i] = i+1;
    }
    // The starting number is at the index which equals the number of D's
    cout << endl << numbers[dCount] << " ";
    numbers[dCount] = -1;
    // Increment starts at the index next to index equal to number of D's.
    int iCount = dCount+1;
    // Next decrement starts at the index previous to index equal to number of D's.
    dCount--;
    for (int i = 0; i < input.length(); i++) {
        if (input[i] == 'I') {
            cout << numbers[iCount] << " ";
            numbers[iCount++] = -1;
        }
        else {
            cout << numbers[dCount] << " ";
            numbers[dCount--] = -1;
        }
    }
    cout << endl;
}

int main() {
 printNumbers("IDDI");
 return 0;
}

Saturday, January 2, 2016

Find if a word is present in a matrix

Find if all the characters of a given word is present in a two dimensional matrix if the matrix can be traversed as described in the image below:

Java Program:

public class MatrixTraversalPrograms {
 public boolean driverForIsWordPresent(char[] in, char[][] matrix) {
  boolean wordFound = false;
  for(int i=0;i<matrix.length;i++) {
   for(int j=0;j<matrix[i].length;j++) {
    if(in[0] == matrix[i][j]) {
     wordFound = isWordPresent(in, matrix, i, j, 0);
    }
    if(wordFound) {
     break;
    }
   }
   if(wordFound) {
    break;
   }
  }
  return wordFound;
 }
 
 public boolean isWordPresent(char[] in, char[][] matrix, int i, int j, int index) {
  if(index == in.length - 1) {
   return true;
  }
  else {
   boolean complete = false;
   //Top Right
   if(i-1 >= 0 && j+1 < matrix[i].length && matrix[i-1][j+1] == in[index+1]) {
    complete = isWordPresent(in, matrix, i-1, j+1, index + 1);
    if(complete) {
     return true;
    }
   }
   //Right
   if(!complete && i >= 0 && i < matrix.length && j+1 < matrix[i].length && matrix[i][j+1] == in[index+1]) {
    complete = isWordPresent(in, matrix, i, j+1, index + 1);
    if(complete) {
     return true;
    }
   }
   //Bottom Right
   if(!complete && i+1 < matrix.length && j+1 < matrix[i+1].length && matrix[i+1][j+1] == in[index+1]) {
    complete = isWordPresent(in, matrix, i+1, j+1, index + 1);
    if(complete) {
     return true;
    }
   }
   //Bottom
   if(!complete && i+1 < matrix.length && j >= 0 && j < matrix[i+1].length && matrix[i+1][j] == in[index+1]) {
    complete = isWordPresent(in, matrix, i+1, j, index + 1);
    if(complete) {
     return true;
    }
   }
   //Bottom Left
   if(!complete && i+1 < matrix.length && j-1 >= 0 && matrix[i+1][j-1] == in[index+1]) {
    complete = isWordPresent(in, matrix, i+1, j-1, index + 1);
    if(complete) {
     return true;
    }
   }
   //Left
   if(!complete && i>=0 && i < matrix.length && j-1 >= 0 && matrix[i][j-1] == in[index+1]) {
    complete = isWordPresent(in, matrix, i, j-1, index + 1);
    if(complete) {
     return true;
    }
   }
   //Top Left
   if(!complete && i-1 >= 0 && j-1 >= 0 && matrix[i-1][j-1] == in[index+1]) {
    complete = isWordPresent(in, matrix, i-1, j-1, index + 1);
    if(complete) {
     return true;
    }
   }
   //Top
   if(!complete && i-1 >= 0 && j >= 0 && j < matrix[i-1].length && matrix[i-1][j] == in[index+1]) {
    complete = isWordPresent(in, matrix, i-1, j, index + 1);
    if(complete) {
     return true;
    }
   }
   return false;
  }
 }
}
 
Unit Tests:
 
import static org.junit.Assert.*;

import org.junit.Test;

import junit.framework.Assert;

public class MatrixTraversalTests {
 
 MatrixTraversalPrograms programInstance = new MatrixTraversalPrograms();
 @Test
 public void testTwoCharacterPresent() {
  char[] in = {'a','b'};
  char[][] matrix = new char[][]{ 
   {'x','b'},
   {'a','x'}
   };
  Assert.assertTrue(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testTwoOnePresent() {
  char[] in = {'a','b'};
  char[][] matrix = new char[][]{ 
   {'x','c'},
   {'a','x'}
   };
  Assert.assertFalse(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testTwoBiggerMatrix() {
  char[] in = {'a','b'};
  char[][] matrix = new char[][]{ 
   {'x','x','x'},
   {'x','b','x'},
   {'a','x','x'}
   };
  Assert.assertTrue(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testTwoRepeated() {
  char[] in = {'a','b'};
  char[][] matrix = new char[][]{ 
   {'x','x','x'},
   {'x','b','x'},
   {'a','b','x'}
   };
  Assert.assertTrue(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testLarge() {
  char[] in = {'M','i','c','r','o','s','o','f','t'};
  char[][] matrix = new char[][]{
   {'x','x','x','x','x','x'},
   {'x','r','o','x','x','x'},
   {'x','x','c','s','x','x'},
   {'x','x','i','o','f','x'},
   {'x','M','x','x','f','x'},
   {'x','x','x','t','x','x'}
   };
  Assert.assertTrue(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testLargePartialPresent() {
  char[] in = {'M','i','c','r','o','s','o','f','t'};
  char[][] matrix = new char[][]{
   {'x','x','x','x','x','x'},
   {'x','r','o','x','x','x'},
   {'x','x','c','s','x','x'},
   {'x','x','i','o','f','x'},
   {'x','M','x','x','f','x'},
   {'x','x','x','x','x','x'}
   };
  Assert.assertFalse(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testOneCharacterPresent() {
  char[] in = {'a'};
  char[][] matrix = new char[][]{
   {'a'}
   };
  Assert.assertTrue(programInstance.driverForIsWordPresent(in, matrix));
 }
 
 @Test
 public void testOneCharacterAbsent() {
  char[] in = {'a'};
  char[][] matrix = new char[][]{
   {'b'}
   };
  Assert.assertFalse(programInstance.driverForIsWordPresent(in, matrix));
 }
}