Showing posts with label inmobi. Show all posts
Showing posts with label inmobi. Show all posts

Monday, April 14, 2014

Suggest the selling time and buying time of a share based on stock price prediction

Problem

You have an API to predict stock values of a particular share,
The API is
StockPrediction predict(int stockid);

where
class StockPrediction{
   Date time:
   float value;
}

using this API develop another API which will suggest the best selling time and buying time of a share (you have to call the predict API N number of times and from the StockPredictions provide the best buy time and sell time for the stock)

Your API can be
BestTiming getBestTiming(int stockid);

where
class BestTiming{
   StockPrediction bestselltime:
   StockPrediction bestbuytime:
}

Example
Input

stock value -  10   |   12   |    7   |    8    |  24  |  35  |   1  |   9
time        -  9am  |  9.30  |   9.45 |   10am  | 11am | 12am |  3am |  4am


Output: buy the stock at 7 rs at 9.45 and sell it for 35 rupees at 12am

(hint: go for the best solution which uses only three variable to get this result)

Solution

We have discussed the similar problem here.
Fill array b with entries s.t. b[0] = a[1]-a[0] .... b[n-1] = a[n]-a[n-1].
Now apply Kadane's Sub sequence sum algorithm on B and Find the indices.
Time O(n), Space O(n).

Design a vending machine like coffee vending machine

This updated information has been further expanded upon on my new website. You can find the updated details here: https://k5kc.com/cs/ood/design-a-vending-machine-like-coffee-vending-machine/.
Broadly, think about what objects are involved in a vending machine:
  • VendingMachine - possibly an abstract class
  • DrinkMachine, SnackMachine, and classes extending VendingMachine
  • VendingProduct - an abstract class?
  • Drink, other classes extending VendingProduct
  • Coke, other classes extending Drink
  • &c, &c.
But I'm sure you can figure that out pretty easily. The nuts and bolts of the machine will take place in some kind of utility class, with methods to accept bills and coins, calculate change, etc.

Also, Getting the coffee will be got from the factory:
public class CoffeeVendingMachine extends VendingMachine{
   private Milk milk;
   private Sugar sugar;
   public Coffee getCoffee(CoffeeTypeEnum coffeeType){
      prepareCoffee(coffeeType);
   }
   private void prepareCoffee(CoffeeTypeEnum coffeeType{
      //internal process for coffee making
   }
}

Note that prepareCoffee is private method, as users don't want to know how coffee is made.

Here is the basic class diagram for vending machine(borrowed from programsfromca):
 Note that VendingMachine composes SelectionPanel, Controller, Product and so on.

References

Sunday, April 13, 2014

Set cover

Problem

There are few sets with some numbers. And you are given an array of numbers. Find combination of sets with minimum number of sets, union of which have all these numbers.

Example
input sets:
A = [1,2,3]
B = [2,5,8]
C = [1,4,5]
D = [3,5,8]

Array to find:
{3,4,8}

Answer:
C + D

Solution

Set cover is NP-hard, so, no polynomial algorithm is known to exist for it.

When you abstract away from the specifics of the problem, it is an integer program (IP). So, you can use any general purpose IP solver such as the one provided in MS-Excel. All general integer programming problems are solved using branch-and-bound method. So, you do not need one specifically for Set Covering alone. All you need to do is to formulate the set covering problem as an integer program and provide it to the solver which should take care of the rest. Folks on SO are unlikely to have a ready-made code available to share with you. Integer Programming/Linear Programming (which forms the basis for integer programming) codes are quite detailed and specialized.

Basically, look at all combinations of 1 set, then 2 sets, etc. until they form a cover.
for size in 1..|S|:
    for C in combination(S, size):
          if (union(C) == U) return C
where combination(K, n) returns all possible sets of size n whose elements come from K.

interface Filter<T> {
    boolean matches(T t);
}
public static void main(String... args) throws IOException {
    Integer[][] arrayOfSets = {
            {1, 2, 3, 8, 9, 10},
            {1, 2, 3, 4, 5},
            {4, 5, 7},
            {5, 6, 7},
            {6, 7, 8, 9, 10},
    };
    Integer[] solution = {1,2,3,4,5,6,7,8,9,10};

    List<Set<Integer>> listOfSets = new ArrayList<Set<Integer>>();
    for (Integer[] array : arrayOfSets)
        listOfSets.add(new LinkedHashSet<Integer>(Arrays.asList(array)));
    final Set<Integer> solutionSet = new LinkedHashSet<Integer>(Arrays.asList(solution));

    Filter<Set<Set<Integer>>> filter = new Filter<Set<Set<Integer>>>() {
        public boolean matches(Set<Set<Integer>> integers) {
            Set<Integer> union = new LinkedHashSet<Integer>();
            for (Set<Integer> ints : integers)
                union.addAll(ints);
            return union.equals(solutionSet);
        }
    };

    Set<Set<Integer>> firstSolution = shortestCombination(filter, listOfSets);
    System.out.println("The shortest combination was "+firstSolution);
}

private static <T> Set<T> shortestCombination(Filter<Set<T>> filter, List<T> listOfSets) {
    final int size = listOfSets.size();
    if (size > 20) throw new IllegalArgumentException("Too many combinations");
    int combinations = 1 << size;
    List<Set<T>> possibleSolutions = new ArrayList<Set<T>>();
    for(int l = 0;l<combinations;l++) {
        Set<T> combination = new LinkedHashSet<T>();
        for(int j=0;j<size;j++) {
            if (((l >> j) & 1) != 0)
                combination.add(listOfSets.get(j));
        }
        possibleSolutions.add(combination);
    }
    // the possible solutions in order of size.
    Collections.sort(possibleSolutions, new Comparator<Set<T>>() {
        public int compare(Set<T> o1, Set<T> o2) {
            return o1.size()-o2.size();
        }
    });
    for (Set<T> possibleSolution : possibleSolutions) {
        if (filter.matches(possibleSolution))
            return possibleSolution;
    }
    return null;
}


References

Sunday, March 30, 2014

Find a line which passes the most number of points

Problem
Given a two dimensional graph with points on it, find a line which passes the most number of points.
Solution
Method 1 - Naive solution
This is the brute force solution. We take point 1, and then point 2 and make a line. Now in the third nested loop, check if point 3 is existing on the same line or not.
Pseudocode
Line findLineWithMaxPoint(Set points){
   foreach Point p1 in points
      foreach Point p2  in (points - {p1}){
         Line l = makeLine(p1,p2);
         int count = 2 //line contains p1 and p2
         foreach(Point p3 in (points-{p1,p2})){
            if(l.contains(p3))
               count++;
         }
         if(maxCount<count){
            count = maxCount;
            resultLine = l;
         }
      }
return resultLine;
}
As we can see there are 3 nested loops, and hence time complexity : O(n^3).

Java code
public class Line {
    private double slope;
    private double intercept;
 
    private final double THRESHOLD = Math.pow(10, -8);
 
    public Line(double slope, double intercept) {
        super();
        this.slope = slope;
        this.intercept = intercept;
    }
 
    public Line(Pair<Double> p1, Pair<Double> p2) {
        this.slope = (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
        this.intercept = (p2.getX() * p1.getY() - p1.getX() * p2.getY())
                / (p2.getX() - p1.getX());
    }
 
    public boolean contains(Pair<Double> p) {
        double x = p.getX();
        double y = p.getY();
        return Math.abs(y - (slope * x + intercept)) < THRESHOLD;
    }
}
 
public static Line findLine(Set<Pair<Double>> points) {
    int maxNumber = -Integer.MAX_VALUE;
    int number = 0;
    Line result = null;
    for (Pair<Double> p1 : points) {
        for (Pair<Double> p2 : points) {
            if (!p1.equals(p2)) {
                number = 0;
                Line line = new Line(p1, p2);
                for (Pair<Double> p : points) {
                    if (line.contains(p))
                        number++;
                }
                if (number > maxNumber) {
                    maxNumber = number;
                    result = line;
                } 
            }
        }
    }
    return result;
}


Method 2 - Use hashtable
Problem with above approach is that the lines may be duplicate. And if we have points p1, and p2 already covered as part of line, which helped us find p3, when we select p1 and p3, we will again select p2.

We have a bunch of line segments, represented as a slope and y-intercept, and we want to find the most common slope and y-intercept. How can we find the most common one? This is really no different than the old "find the most common number in a list of numbers" problem. We just iterate through the lines segments and use a hash table to count the number of times we've seen each line.

This can be solved in O(n^2) time and O(m) space. where m is the distinct number of lines among all given points.

  1. Use a hash table - key is line and number of appearance of line as value.
  2. For each pair of points find the line in slope y intercept form
  3. if the line is not there in hash table, add it to the hash table with appearance value 1
  4. if the line is already in hash table, increment the appearance value
  5. line with the max number of appearance in the hash table is the result.

Java code
In java we have to implement a hashCode() method to make the class object uniquely identifiable by the hashtable.
public static Line findBestLine(GraphPoint[] points) {
    Line bestLine = null;
    HashMap<Line, Integer> line_count = new HashMap<Line, Integer>();
    for (int i = 0; i < points.length; i++) {
        for (int j = i + 1; j < points.length; j++) {
            Line line = new Line(points[i], points[j]);
            if (!line_count.containsKey(line)) {
                line_count.put(line, 0);
            }
            line_count.put(line, line_count.get(line) + 1);
            if (bestLine == null
                    || line_count.get(line) > line_count.get(bestLine)) {
                bestLine = line;
            }
        }
    }
    return bestLine;
}
 
public class Line {
    private static double epsilon = .0001;
    public double slope;
    public double intercept;
    private boolean infinite_slope = false;
 
    public Line(GraphPoint p, GraphPoint q) {
        if (Math.abs(p.x - q.x) > epsilon) { // if x’s are different
            slope = (p.y - q.y) / (p.x - q.x); // compute slope
            intercept = p.y - slope * p.x; // y intercept from y=mx+b
        } else {
            infinite_slope = true;
            intercept = p.x; // x-intercept, since slope is infinite
        }
    }
 
    public boolean isEqual(double a, double b) {
        return (Math.abs(a - b) < epsilon);
    }
 
    @Override
    public int hashCode() {
        int sl = (int) (slope * 1000);
        int in = (int) (intercept * 1000);
        return sl | in;
    }
 
    @Override
    public boolean equals(Object o) {
        Line l = (Line) o;
        if (isEqual(l.slope, slope) && isEqual(l.intercept, intercept)
                && (infinite_slope == l.infinite_slope)) {
            return true;
        }
        return false;
    }
}


  • Be careful about the calculation of the slope of a line. The line might be completely vertical. We can keep track of this in a separate flag (infinite_slope). We need to check this condition in the equals method.
  • Remember that when we perform division to calculate the slope, division is not exact. Therefore, rather than checking to see if two slopes are exactly equal, we need to check if they’re different by greater than epsilon, in our case 10-8.
Method 3 - Hough transform
Not really sure how hough transform works, but you can read more here.

References
http://tianrunhe.wordpress.com/2012/04/03/find-a-line-which-passes-the-most-number-of-points/