Wednesday, 31 May 2017

Determining a sequence is sorted or not


If you have a list or array of elements then how should we determine the given sequence is either sorted in ascending or descending order.

There are many ways of finding it  but the following solution provides a solution in one iteration so complexity is O(n).

We need to compare the elements such that either elements are either increasing or decreasing  , if this condition is not matching then unsorted sequence otherwise its a sorted sequence.

/**
 * @author sachin.srivastava
 * @tek9g.blogpspot.com
 * {@code checking various scenarios of handling the sorting cases.}
 */

//checking if a list is sorted means asceding or descending in either way.
//complexity is O(n) beacaue of traversal of n elements of the list
public static <T extends Comparable<T>> boolean isSorted(List<T> list) {
if(list == null || list.isEmpty()){
return false;
}
if(list.size() == 1) {
return true;
}
T prev =null;
boolean asc = true;
boolean desc = true;
for (T t : list) {
//ascending
if(prev!=null && prev.compareTo(t) > 0 ){
asc = false;
//descending
if(prev!=null && prev.compareTo(t) < 0 ){
desc = false;
}
prev  = t;
}
return asc || desc;

}

Testcases

            System.out.println(isSorted(Arrays.asList(1,2,4,5)));//true
System.out.println(isSorted(Arrays.asList(5,2,4,5)));//false
System.out.println(isSorted(Arrays.asList("abc","bcd","def","fgh")));//true
System.out.println(isSorted(Arrays.asList("b","a","c","d")));//false


Enjoy the coding !!!!

Monday, 22 May 2017

Knight minimum moves to get checkmate in chess - An algorithm challenge

 


Problem Statement :   

Given on a chessboard a Black Knight position (x, y) and the opponent white King position is at the the coordinate of (m, n), assuming the King is not moving to any place, then find the minimum moves of Black Knight requires to get a checkmate and to win the game. [Coordinates are shown in the above picture]

Solution : 

The Knight moves with respect to its current position (x,y)  in the 8 possible coordinates : 

 (x+2 , y+1 ) ,  (x+2 , y-1 ) ,  (x-2 , y+1 ) , (x-2 , y-1 ) ,  (x+1 , y+2 ) ,  (x-1 , y+2 ) ,  (x+1 , y-2 ) , 
(x-1 , y-2 ) 

So it can be noted that position (x,y ) can be treated as the head vertex of the Graph and reaming 8 possible coordinates are adjacent vertex of the  graph. So we need to find all the possible paths of reaching to king ( m,n ) and figure out then shortest path among all. 

There are 2 ways to solve the problem : 

1.  Dijkstra's algorithm 

2.  Breadth First Traversal or BFS

We will follow the 2 option of BFS to solve it  and following code snippet written in java to demonstrate the solution of the above problem.

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

/**
 * @author sachin.srivastava
 * tek9g.blogspot.coml
* @email tek9gworld@gmail.com
 *
 */
public class KnightChess {
public static int  traverseCount(Node start , Node end){
if(start ==null || end == null || (start.x == end.x && start.y == end.y) ){
return 0;
List<Node> visitedNodes = new ArrayList<>();
Queue<Node> queue = new LinkedList<>();
start.visited = true;
queue.add(start);
int minMoves = 0;
while (!queue.isEmpty()) {
Node head = queue.poll();
if(head.x < 1 || head.x > 8 || head.y <1 || head.y > 8 ){
continue;
}
if(head.x == end.x && head.y == end.y){
head.visited = true;
break;
}
List<Node> adjNodes = adjNodes(head, visitedNodes, end);
int count = printVisitedNodes(adjNodes,end,head);
if(count > 0){
if(minMoves <= count -1){
minMoves = count-1;
}
}
for (Node node : adjNodes) {
if(!node.visited){
queue.add(node);
node.visited = true;
}
}
}
return minMoves;
}
public static int printAllNodes(Node node, int count){
if(node == null){
System.out.print("\n");
return count;
}
count++;
System.out.print( "("+ node.x + "," +node.y + ")" + " ");
return printAllNodes(node.parent,count);
}
public static int printVisitedNodes(List<Node> visitedNodes,Node end,Node parent){
if(visitedNodes!=null && !visitedNodes.isEmpty()){
for (Node node : visitedNodes) {
if(matchEndNode(node, end)){
return printAllNodes(node,0);
}
}
}
return 0;
}
public  static boolean nodeVisited(Node node,List<Node> visitedNodes,Node end ){
boolean flag = false;
if(node.x <1 || node.x >8 || node.y <1 || node.y >8 || (node.x == 1 && node.y == 1 || node.x==8 && node.y==8)) {
node.visited = true;
return true;
}
if(node!=null && !node.visited && visitedNodes!=null && !visitedNodes.isEmpty()){
for (Node node2 : visitedNodes) {
if(node2.x == node.x && node2.y == node.y ){
node.visited = true;
node2.visited = true;
flag= true;
break;
}
}
}
return flag;
}
public static boolean matchEndNode(Node start, Node end){
if(start.x== end.x && start.y == end.y){
return true;
}
return false;
}
public static List<Node> adjNodes(Node start , List<Node> visitedNodes,Node end){
int x = start.x;
int y = start.y;
Node parent = start;
List<Node> adjNodes = new ArrayList<>();
if(!nodeVisited(new Node(x+2, y+1,parent), visitedNodes,end)){
adjNodes.add(new Node(x+2, y+1,parent));
if(matchEndNode(new Node(x+2, y+1,parent), end)){
return adjNodes;
}
}
if(!nodeVisited(new Node(x+2, y-1,parent), visitedNodes,end)){
adjNodes.add(new Node(x+2, y-1,parent));
if(matchEndNode(new Node(x+2, y-1,parent), end)){
return adjNodes;
}
}
if(!nodeVisited(new Node(x+1, y+2,parent), visitedNodes,end)){
adjNodes.add(new Node(x+1, y+2,parent));
if(matchEndNode(new Node(x+1, y+2,parent), end)){
return adjNodes;
}
}
if(!nodeVisited(new Node(x-1, y+2,parent), visitedNodes,end)){
adjNodes.add(new Node(x-1, y+2,parent));
if(matchEndNode(new Node(x-1, y+2,parent), end)){
return adjNodes;
}
}
if(x > end.x){
if(!nodeVisited(new Node(x-2, y+1,parent), visitedNodes,end)){
adjNodes.add(new Node(x-2, y+1,parent));
if(matchEndNode(new Node(x-2, y+1,parent), end)){
return adjNodes;
}
}
if(!nodeVisited(new Node(x-2, y-1,parent), visitedNodes,end)){
adjNodes.add(new Node(x-2, y-1,parent));
if(matchEndNode(new Node(x-2, y-1,parent), end)){
return adjNodes;
}
}
}
if(y > end.y){
if(!nodeVisited(new Node(x+1, y-2,parent), visitedNodes,end)){
adjNodes.add(new Node(x+1, y-2,parent));
if(matchEndNode(new Node(x+1, y-2,parent), end)){
return adjNodes;
}
}
if(!nodeVisited(new Node(x-1, y-2,parent), visitedNodes,end)){
adjNodes.add(new Node(x-1, y-2,parent));
if(matchEndNode(new Node(x-1, y-2,parent), end)){
return adjNodes;
}
}
}
return adjNodes;
}

static class Node{
int x;
int y;
Node parent;
boolean visited;
public Node(int x , int y, Node parent) {
this.x = x;
this.y = y;
this.parent = parent;
}
}
public static void main(String[] args) {
Node start = new Node(1, 1, null);
Node end = new Node(1,7, null);
System.out.println("Minimum moves for knight="+ traverseCount(start, end));
}
}


Input : 1 , 1 , 1, 7 

Output : 

(1,7) (3,6) (4,4) (3,2) (1,1) 
(1,7) (2,5) (4,4) (3,2) (1,1) 
(1,7) (3,6) (2,4) (3,2) (1,1) 
(1,7) (2,5) (1,3) (3,2) (1,1) 
(1,7) (3,6) (4,4) (2,3) (1,1) 
(1,7) (2,5) (4,4) (2,3) (1,1) 
(1,7) (3,6) (1,5) (2,3) (1,1) 
Minimum moves for knight=4

Input : 2 , 1 , 6, 5

Output :  

(6,5) (8,4) (6,3) (4,2) (2,1) 
(6,5) (7,3) (6,1) (4,2) (2,1) 
(6,5) (5,3) (6,1) (4,2) (2,1) 
(6,5) (7,3) (5,4) (4,2) (2,1) 
(6,5) (4,6) (5,4) (4,2) (2,1) 
(6,5) (5,3) (3,4) (4,2) (2,1) 
(6,5) (4,6) (3,4) (4,2) (2,1) 
(6,5) (7,3) (5,4) (3,3) (2,1) 
(6,5) (4,6) (5,4) (3,3) (2,1) 
(6,5) (7,3) (5,2) (3,3) (2,1) 
(6,5) (4,4) (5,2) (3,3) (2,1) 
(6,5) (5,7) (4,5) (3,3) (2,1) 
(6,5) (4,6) (2,5) (3,3) (2,1) 
(6,5) (4,4) (2,5) (3,3) (2,1) 
(6,5) (5,3) (3,4) (1,3) (2,1) 
(6,5) (4,6) (3,4) (1,3) (2,1) 
(6,5) (5,3) (3,2) (1,3) (2,1) 
(6,5) (4,4) (3,2) (1,3) (2,1) 
(6,5) (4,6) (2,5) (1,3) (2,1) 
(6,5) (4,4) (2,5) (1,3) (2,1) 
Minimum moves for knight=4

Input : 5 , 5 , 6, 6

Output : 

(6,6) (7,4) (5,5) 
(6,6) (4,7) (5,5) 
Minimum moves for knight=2


Enjoy the chess and coding !!!!!

Thursday, 18 May 2017

Merging M sorted sequence into one sequence in Java


Suppose you have M number of List/Array/Sequence  and each one is sorted with total of N number of elements. So  best optimal way to solve it with the the complexity O(NlogM) time using a heap.

Minimum of each sequence can form a heap with the O(logM) time to insert elements in the heap and O(1) time to delete an element.

Each element would take O(logM) time to insert in the heap and with the total number of elements N, it gives an O(NlogM) time solution. 


In Java 1.5 onwards  PriorityQueue/PriorityBlockingQueue are being introduced to cater as priority heap.


We are really thankful to Joshua Bloch, father of Java Collection Framework, to enlighten with the real world of programming in Java. 


Following are the description available in the Oracle Docs Java 1.5 : 



An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used. A priority queue does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException).

The head of this queue is the least element with respect to the specified ordering. If multiple elements are tied for least value, the head is one of those elements -- ties are broken arbitrarily. The queue retrieval operations poll,removepeek, and element access the element at the head of the queue.

A priority queue is unbounded, but has an internal capacity governing the size of an array used to store the elements on the queue. It is always at least as large as the queue size. As elements are added to a priority queue, its capacity grows automatically. The details of the growth policy are not specified.

This class and its iterator implement all of the optional methods of           the Collection and Iterator interfaces. The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).


Note that this implementation is not synchronized. Multiple threads should not access a PriorityQueue instance concurrently if any of the threads modifies the queue. Instead, use the thread-safe PriorityBlockingQueueclass.
Implementation note: this implementation provides O(log(n)) time for the enqueing and dequeing methods (offerpollremove() and add); linear time for the remove(Object) and contains(Object) methods; and constant time for the retrieval methods (peekelement, and size).

This class is a member of the Java Collections Framework.

Lets see some example to elaborate the solution : 


/**
 * @author sachin srivastava
 * tek9g.blogspot.com
 *
 */
public class MergingSortedSequence {
public static void main(String[] args) {
int[] arr1  = {1,3,6,4,8,90,133};
int[] arr2  = {2,3,1,17,18};
int[] arr3  = {4,5,6,8,11};
int[] arr4  = {125,9,10,13,34};
int[] arr = new int[arr1.length + arr2.length + arr3.length + arr4.length];
PriorityQueue<Integer> prq = new PriorityQueue<>();
for (int i = 0; i < arr.length; i++) {
if(i<arr1.length){
prq.add(arr1[i]);
}
if(i<arr2.length){
prq.add(arr2[i]);
}
if(i<arr3.length){
prq.add(arr3[i]);
}
if(i<arr4.length){
prq.add(arr4[i]);
}
}
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}
}
}

Output : 1 1 2 3 3 4 4 5 6 6 8 8 9 10 11 13 17 18 34 90 125 133 


Output is sorted in the ascending order  using Min heap .


Point here is if we don't have the M sorted sequence even then using the PriorityQueue , we can have a sorted collection .


Let see the example using the Random number generation : 



public static void main(String[] args) {
/**
 * @author sachin srivastava
 * tek9g.blogspot.com
 *
 */
PriorityQueue<Integer> prq = new PriorityQueue<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
int rand = random.nextInt(20);
System.out.print(rand +" ");
prq.add(rand);

}
System.out.println("\n------\n");
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}

}
  
Output : 

Random generated sequence : 



8 11 18 14 6 5 10 19 7 3 3 17 14 10 18 8 17 5 5 9 
------
Sorted merged sequence : 


3 3 5 5 5 6 7 8 8 9 10 10 11 14 14 17 17 18 18 19 


If you are working in a multithreaded  environment then these thread should not have concurrent access to the PriorityQueue and if any of the thread is modifying the queue then to make it thread safe , we need to use PriorityBlockingQueue instead of PriorityQueue which has been designed to cater the concurrent modification problem.

In the above mentioned scenarios  Min heap PriorityQueue is implemented which is by default the implementation of the queue.

If we want to create Max heap using the PriorityQueue then we need to pass the comparator to it and then output will be in the descending order. 

Consider the above random number problem : 

public static void main(String[] args) {
/**
 * @author sachin srivastava
 * tek9g.blogspot.com
 *
 */
//Max heap by passing a comparator
PriorityQueue<Integer> prq = new PriorityQueue<>((x,y)-> y-x);
Random random = new Random();
for (int i = 0; i < 20; i++) {
int rand = random.nextInt(20);
System.out.print(rand +" ");
prq.add(rand);

}
System.out.println("\n------\n");
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}

}
  
Output : 

Random generated sequence : 



17 0 4 12 9 11 5 12 12 12 3 18 19 9 9 17 8 19 1 14  
------
Sorted merged sequence using the max heap in the descending order : 



19 19 18 17 17 14 12 12 12 12 11 9 9 9 8 5 4 3 1 0  


Enjoy the beautiful world of Java and coding !!!!!!

Saturday, 13 May 2017

Choosing MongoDB - an awesome NoSQL database!!!!





MongoDB, a NoSQL database, is leading the market with many commendable features to its credit. These include exemplary features of MongoDB such as JSON or BSON Data Storage, Power Performance, and Horizontal Scaling. These features come together to create the most powerful database that can monitor, manage, and process huge volume of data in a rather systematic way.     

Lets see first of all NoSQL databases popularity trend which is as shown in the following chart :        

                                                                                  


From the above chart , MongoDB  clearly a winner in terms of popularity and its rank among top 5 DBMS  of the world and have DB-Engine score more than 300 which is an outstanding score for a DBMS.


MongoDB as compared to traditional RDBMS have some very unique features which are vital in the web applications development and its growth is many fold day by day and its user base is getting strong with the strong community of user . Making it a fastest growing NoSQL DB for the development world. 

Best MongoDB features are:

Pros : 
  • Schema less or Dynamic schemas which makes it very flexible and highly helpful in solution of highly complex problem. 
  • Structure of a single object is clear
  • No complex joins
  • Deep query-ability
  • Easy tuning.
  • Ease of scale-out.
  • Conversion / mapping of application objects to database objects not needed.
  • Uses internal memory for storing the (windowed) working set, enabling faster access of data.
  • Document Oriented and NoSQL database.
  • Supports Aggregation
  • Uses JSON like  BSON format which is binary JSON
  • Sharding (Helps in Horizontal Scalability)
  • Supports Ad Hoc Queries
  • Indexing (Any field in MongoDB can be indexed)
  • MongoDB Replica Set (Provides high availability)
  • Supports Multiple Storage Engines
  • Capped Collection
  • High Availability
  • Load Balancing
  • Easy Scalability
  • Powerful Security
  • Automatic Fail-over
  • Advanced User Management
  • Powerful query engine
  • Geospatial support with the geospatial indexing capability - very useful feature for those product which uses geo location to build their logic . Many application can be made using this feature.
  • High Performance
  • Can store big files without changing your data structure - GridFS is main core for managing files and wonderfully handle the big size files.
  • Has Text search integrated facility also helpful is searching 
  • Map Reduce - One of the key feature increasing the capability of processing of large volumes data set into aggregated result set. 
  • Master Slave Replication  - In case of any failure of Master  Slave becomes the Master and Master becomes Slave. So a great fail over support in it.
  • Data Center Awareness - MongoDB provides a number of features that allow application developers and database administrators to customize the behaviors of a sharded cluster or replica set deployment so that MongoDB may be more  "data center aware" or allow operational  and location-based separation.
  • Replica Sets Distributed Across Two or More Data Centers 
  • Easy Deployment 
  • Simple to maintain and not necessary to have DBA for it.
  • Very useful in the case where  high write load is more 

Cons :

  • A downside of NoSQL is that most solutions are not as strongly ACID-compliant (Atomic, Consistency, Isolation, Durability) as the more well-established RDBMS systems.
  • Complex transaction
  • No function or stored procedure exists where you can bind the logic

Who are using MongoDB

Currently more than 4500 customers() are using mongo  and some of them are : 

Expedia , MetLife , Cisco, Facebook , Adobe, IBM, SAP, Twitter , Forbes , BusinessInsider and many more big names of the world.

One can see through the complete list of users link 

Good For:

  • E-commerce product catalog.
  • Blogs and content management.
  • Real-time analytics and high-speed logging, caching, and high scalability.
  • Configuration management.
  • Maintaining location-based data — Geospatial data.
  • Mobile and social networking sites.
  • Evolving data requirements.
  • Loosely coupled objectives — the design may change by over time.

Not so Good For:

  • Highly transactional systems or where the data model is designed up front.
  • Tightly coupled systems
  • Multi-Object Transactions: MongoDB only supports ACID transactions for a single document.
  • SQL: SQL is well-known and a lot of people know how to write very complex queries to do lots of things. This knowledge is transferrable across a lot of implementations where MongoDB's queries language are specific to it.
  • Strong ACID guarantees: MongoDB allows for things like inconsistent reads which is fine in some applications, but not in all.
  • Traditional BI: A lot of very powerful tools exist that allow for OLAP and other strong BI applications and those run against traditional SQL database.

Enjoy the Mongo!!!!

Wednesday, 10 May 2017

Compressing a String - An Amazon Problem



Problem Statement
Compress a given string "aabbbccc" to "a2b3c3" constraint: inplace compression, no extra space to be used  assumption : output size will not exceed input size.. ex input:"abb" -> "a1b2" buffer overflow.. such inputs will not be given.
Solution : 
Since no extra is to be use hence we can't use recursion in this case . we need to operate on array to make the operation in place . lets see a simple solution to this problem though many ways of doing it possible so one of them I am mentioning here : 
public  static String compressString(String input){
/*
* @sachin srivastava
* tek9g.blogspot.com
* */
StringBuilder sb = new StringBuilder();
if(input == null || input.isEmpty()){
return null;
} else if(input.length() <= 2){
return input;
}
char[] ch = input.toCharArray();
int lenght = ch.length;
int count = 1;
for (int i = 0; i <=lenght-1; i++) {
if(i!=lenght-1 && ch[i] == ch[i+1] ){
count++;
} else {
sb.append(ch[i] + "" +count);
count = 1;
}
}
if(input.length() < sb.toString().length()){
System.out.println("invalid input buffer overflow");
}
return sb.toString();
}

Input1 : aaaaaaaabbcccccccgggggggaaaaaaaeeeeeef

Output1 : a8b2c7g7a7e6f1
Input2 :  abb
Output : invalid input buffer overflow

a1b2

Input3 : abbrrrrtttttgggaaawwww

Output3 : a1b2r4t5g3a3w4

Time Complexity : O(n)
Space Complexity : O(1)  -- in place 

Enjoy coding !!!!