Combinations of a String

Problem:
Write an algorithm to print all possible combinations of characters in a string.

Solution:
Since we need to generate combinations, we can start with a single character and then continue to add a character to combinations we have seen so far.

Let’s use “XYZ” as an example.

public void buildTree(String input, StringBuffer output, int k)
{
    for (int i = k; i < input.length(); i++)
    {
        output.append(input.charAt(i));
        buildTree(input, output, i + 1);
        output.deleteCharAt(output.length() - 1);
    }
} 

public static void main(String[] args){
     buildTree("XYZ", new StringBuffer(), 0);
}

Dry Run just to give an idea:

X–>Y–>Z
–>Z–>Y

Y–>X–>Z
–>Z–>X

Z–>Y–>X
–>X–>Y

Gold for 7 Days of Work Puzzle

Problem Statement:

You’ve got someone working for you for seven days and a gold bar to pay them. You must pay the worker for their work at the end of every day. If you are only allowed to make two breaks in the gold bar, how do you pay your worker?
(Assuming equal amount of work is done during each day thus requiring equal amount of pay for each day)

Answer

The trick is not to try and how to cut in such a way to make 7 equal pieces but rather to make transactions with the worker. Make two cuts on the gold bar such that you have the following sizes of bars.

1/7, 2/7 and 4/7.

Day Pay Take Back Total Paid Amount Balance Amount
1 1/7 N/A 1/7 2/7, 4/7
2 2/7 1/7 2/7 1/7, 4/7
3 1/7 N/A 3/7 4/7
4 4/7 1/7, 2/7 4/7 2/7, 1/7
5 1/7 N/A 5/7 2/7
6 2/7 1/7 6/7 1/7
7 1/7 N/A 7/7 N/A

Fastest 3 out of 25 Horses Problem

Problem Statement

You have 25 horses, and you want to pick the fastest 3 horses out of those 25. Each race can have maximum of 5 horses at the same time. What is the minimum number of races required to find the 3 fastest horses without using a stopwatch?

Solution

Let’s say that we have 5 races of 5 horses each, so each row in the table above represents a race.

H1 H2 H3 H4 H5
H6 H7 H8 H9 H10
H11 H12 H13 H14 H15
H16 H17 H18 H19 H20
H21 H22 H23 H24 H25

Let each row represent a race.

Step 1: Perform 5 races of each set.

Result:

1st 2nd 3rd 4th 5th
H1 H2 H3 H4 H5
H6 H7 H8 H9 H10
H11 H12 H13 H14 H15
H16 H17 H18 H19 H20
H21 H22 H23 H24 H25

Step 2: Elimination by logical analysis:

  • We can eliminate the slowest 2 horses in each group since those horses are definitely not in the top 3
  • The 5 group leaders are not necessarily the 5 fastest horses, therefore race those 5 horses against each other (H1, H6, H11, H16, and H21) {Race 6}, Let’s say that the 3 fastest in that group are H1, H6, and H11 – automatically we can eliminate H16 and H21 since those 2 are definitely not in the top 3
  • We can automatically eliminate all the horses that H16 and H21 competed against in the preliminary races as they were slower than H16 and H21
  • We also know that H1 is the fastest horse in the group since he was the fastest horse out of the 5 group leaders
  • if H6 and H11 are the 2nd and 3rd fastest in the group leaders, then we should be able to eliminate H8 since H6 raced against him and he was in 3rd place in that race
  • We can also eliminate H12 and H13 since H11 was the 3rd fastest in the group leaders, and H12 and H13 were slower than H11
  • This leaves us with the following horses to determine the 2nd and 3rd fastest horses:
H2 H3 H6 H7 H11

Race the last Set {Race 7} to get the Top 2nd and 3rd racers with H1 as the fastest.

Total number of Races: 7

100 floors with 2 eggs puzzle

Problem Statement:

There is a building of 100 floors  If an egg drops from the Nth floor or above it will break. If it’s dropped from any floor below, it will not break. You’re given 2 eggs.

Give an Algorithm to find N, while minimizing the number of drops for the worst case.

Solution:

The Problem comes with a general equation as X(Max Number of floors) = n*n;

So in this case for example, X= 100 Floors( => n=10)

now use the value n to traverse. This means that drop the first egg from 10th floor, then 20th floor, then 30th and so on up to 90.

The floor from which it breaks, say 60th, then go back 10 floors and try each floor to find N.

After Floor 90, Start moving 1 by 1.

Worst case scenario:

eggs break at 99th floor.

Egg drops: 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70 -> 80 -> 90 -> 91 -> 92 -> 93 -> 94 -> 95 -> 96 -> 97 -> 98 -> 99

Max Attempts: 18

The water jug problem

We have three water jugs, and each can hold 3oz., 5oz., and 8oz. of water, respectively.
Without the possibility of water spilling when poured from one jug to another, and given that the jugs have no calibration, how do we divide the 8oz. of water equally among two jugs?

We will define a class named State holding the capacity of A and B jars.
It should be noted that only 2 jars are sufficient to define a state, as water held in third jar can be calculated by subtracting the sum of two from the total.

Define class State like this…

package mystate;
import bfs.threejugproblem.NotSupportedException;
import java.util.ArrayList;
import java.util.List;
public class State
{
int a=0;//3
int b=0;//5
int c=8;//8

public State(int a, int b)
{
this.a=a;
this.b=b;
this.c=8-a-b;
}
public boolean isGoal()
{
return (b==4 && c==4);
}
public boolean equals(Object xx)
{
State x = (State) xx;
if(this.a==x.a && this.b==x.b && this.c==x.c)
{
return true;
}
else
{
return false;
}
}
public int hashCode()
{
return 8;
}
public List getChildren()
{
List children = new ArrayList();
// a -> b
if(a!=0 && b!=5)// if a is not empty
{
if(a+b<=5)
{
children.add(new State(0, a+b));
}
else
{
children.add(new State(a+b-5,5));
}
}
//a->c
if(a!=0 && c!=8)
{
// We are pouring completely from a to c
// a will be 0
// b will be 8-a-c
// c will be a+c
children.add(new State(0, 8-a-c));
}
//b->a
if(b!=0 && a!=3)
{
if(a+b<=3)
{
children.add(new State(a+b, 0));
}
else
{
children.add(new State(3, a+b-3));
}
}
// b->c
if(b!=0 && c!=8)
{
// We are pouring completely from b to c
// a will be 8-b-c
// b will be 0
// c will be b+c
children.add(new State(8-b-c, 0));
}
//c->a
if(c!=0 && a!=3)
{
if(c+a<=3)
{
children.add(new State(c+a, 8-c-a));
}
else
{
// a will be full i.e. 3 liters
// b will be 8-c-a
// c will be c+a-3
children.add(new State(3, 8-c-a));

}
}
// c->b
if(c!=0 && b!=5)
{
if(c+b<=5)
{
children.add(new State(8-c-b , c+b));
}
else
{
children.add(new State(8-c-b, 5));
}
}
return children;
}
@Override
public String toString()
{
return "{"+a+","+b+","+c+"}";
}
}

Depth First Search Algorithm

public class DFSThreeJugProblem 
{
public static void main(String[] args)
{
State currentState = new State(0,0);
List visitedStates=new ArrayList();
// Check if the current State has a solution
// given a set of visited States.
dfs(currentState, visitedStates);
}
public static void dfs(State currentState, List vStates)
{
// if it is GOAL
if(currentState.isGoal())
{
// That's it we are done.
for(State v : vStates)
{
System.out.println(v);
System.out.println(currentState);
}
System.exit(0);
}

// if visisted state contains currentState, then just return.
// This is the wrong branch, and we need not traverse it further.
if(vStates.contains(currentState))
return;

// Add current state to visited states.
vStates.add(currentState);

// Make clone of visited states.
List clonedVStates = new ArrayList(vStates);
// Find the set of possible children of current state.
List children = currentState.getChildren();
for(State c : children)
{
// if a children C is not in the visited states
// again call DFS on current child and visited States.
if(!clonedVStates.contains(c))
{
dfs(c, clonedVStates);
}
}
}
}

Breadth First Search algorithm…

public class BFSThreeJugProblem 
{
private static List visitedStates=new ArrayList();
private static Queue stateQueue = new LinkedList();
public static void main(String[] args) throws NotSupportedException
{
State currentState = new State(0,0);
// Add current state to state Queue.
stateQueue.add(currentState);
do
{
// Get the first Element from Queue.
State firstElementInQueue = stateQueue.peek();
// If the first Element is the Goal
// We are done.
if(firstElementInQueue.isGoal())
{
for(State p : visitedStates)
{
System.out.println(p.toString());
}
// There is no recursion here, so simple return would do.
return;
}
else
{
// Add firstElement to visited States
visitedStates.add(firstElementInQueue);
// Get the children of first element
List children = firstElementInQueue.getChildren();
for(State v : children)
{
// if children has not already been visited.
if(!visitedStates.contains(v))
{
// add the child to state Queue.
stateQueue.add(v);
}
}
// Remove the first element from state queue.
stateQueue.remove(firstElementInQueue);
}
// do this till state queue is empty.
}while(!stateQueue.isEmpty());
}
}

Comparable vs Comparator

There are many articles available on internet for this. But still I would write something about it.

What when and why?

A Comparable class is a class, which can be compared with the objects of its own type. Let us take an example of a book.

public class Book implements Comparable {
    String title;
    int    isbn;

    Book(String title, int isbn) {
        this.title = title;
        this.isbn  = isbn;
    }
    /* This method will be the default method used 
       to sort Book objects in a list or Array */
    public int compareTo(Object object) {
    // It should throw NullPointerException if object passed is null
    if (object==null)
    {
        throw new NullPointerException("compareTo: Argument passed is null");
    }
        Book other = (Book) object;
        if (this.title.equals(other.title)) {
            return this.isbn - other.isbn;
        }
        return this.title.compareTo(other.title);
    }
}

The moment your class implements Comparable, you can then use

List list = new LinkedList();
        list.add(new Book("Patterns", 12345));
        list.add(new Book("Apples", 34567));
        list.add(new Book("Examples", 23456));

        Collections.sort(list);


Using this you can sort your list.

But what if now, you want to add or use another sorting criteria defined in Book class… Here comes the need of Comparator.
There are two ways listed here to use the Comparator class.

First method

We create a anonymous class that implements Comparator and overrides compare method.

Collections.sort(list, new Comparator() {
            public int compare(Object obj1, Object obj2) {
                if(obj1 == null || obj2 == null){
                    throw new NullPointerException("compareTo: Argument passed is null");
                }
                Book book1 = (Book) obj1;
                Book book2 = (Book) obj2;
                return book1.isbn - book2.isbn;
            }
        });

 

Second Method

You define a class that implements Comparator like as below.

class BookComparator implements Comparator{
   
    public int compare(Object book1, Object book2){
   
        int b1= ((Book)book1).isbn;        
        int b2= ((Book)book2).isbn;
       
        if(b1> b2)
            return 1;
        else if(b1< b2)
            return -1;
        else
            return 0;    
    }
   
}

And use this newly defined comparator class as an argument to Collections.sort.

Arrays.sort(list, new BookComparator ());

Good reasons to use Comparator interface

  • I do not have permissions to edit the Book class.
  • Book class already implements Comparable interface, but I want to sort the objects using a different criteria
  • I want to have more than 1 criterias to sort the objects in different orders.

Reasons to implement Comparable interface

  • I want my class to have a default sorting criteria that can be used by the users of my class
  • Usually, one would like to sort the objects based on primary key

Few good links on this topic are here http://www.javadeveloper.co.in/java-example/java-comparator-example.htmlhttp://grdurand.com/static/presentation_four/comparable.htmlhttp://javarevisited.blogspot.com/2011/06/comparator-and-comparable-in-java.html