This question was asked in a forum. Any suggestions?
There is a pyramid with 1 cup at level , 2 at level 2 , 3 at level 3 and so on.. It looks something like this >
The pascal triangle solution for calculating binomial coefficient can be used to solve this problem. We just need to tweak the algorithm a little bit and instead of calculating binomial coefficients, we calculate the water level. Given ith cup, we calculate level and index to find out where the cup sits in the triangle.
The cups are modelled as
0 Level 1
1 2 Level 2
3 4 5 Level 3
getIndex() and getLevel() returns the index and level. Index and Level starts at 1.
public static int getIndex(int i) {
int totalNodes = i + 1;
double d = (-3 + Math.sqrt(9 - 8*(1-totalNodes)))/2;
int level = (int)Math.floor(d);
int total = ((level+1)*(level+2))/2;
int index = 0;
if(total==totalNodes) index = level;
else{
level++;
index = totalNodes - total - 1;
}
return ++index;
}
public static int getLevel(int i) {
int totalNodes = i + 1;
double d = (-3 + Math.sqrt(9 - 8*(1-totalNodes)))/2;
int level = (int)Math.floor(d);
int total = ((level+1)*(level+2))/2;
int index = 0;
if(total==totalNodes) index = level;
else{
level++;
index = totalNodes - total - 1;
}
return ++level;
}
k is kth cup starting at 0. C is cup capacity, L is total water.
public static double getWaterLevel(double C, double L, int k) {
int n = getLevel(k);
int index = getIndex(k);
double[] water = new double[index+1];
water[1] = L;
for(int i = 2; i <= n; i++)
{
boolean overflowed = false;
for(int j = Math.min(i, index); j > 0; j--) {
double over = 0;
if(water[j]>C) over = (water[j]-C)/2;
if(water[j-1]>C) over += (water[j-1]-C)/2;
water[j] = over;
if(!overflowed && over!=0) overflowed=true;
}
if(!overflowed) break; // no more overflow. stop
}
return water[index] > C ? C : water[index];
}