Skip to content

Instantly share code, notes, and snippets.

@DigiTec
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DigiTec/16151a5d41e2d02b8f30 to your computer and use it in GitHub Desktop.
Save DigiTec/16151a5d41e2d02b8f30 to your computer and use it in GitHub Desktop.
This uses similar features to Pascals Triangle to solve the champagne tower problem. Since I found two variants of the problem, I've solved both. The first variant gives the row and the column so no decomposition is necessary for the inputs. The second variant assigns cup numbers starting from 1 and assigning from top to bottom left to right as …
double ChampagneTower(double water, double capacity, int row, int col);
double ChampagneTower(double water, double capacity, int cup)
{
// The cup id is from left to right. We want the row and column in the triangular
// array which is basically the triangular root and our remainder.
int triangular_root = ceil((sqrt(8*cup+1)-1)/2);
int column = cup - ((triangular_root*(triangular_root-1))/2);
return ChampagneTower(water, capacity, triangular_root, column);
}
double ChampagneTower(double water, double capacity, int row, int col)
{
// Computed the reflected glass to reduce time complexity
col = min(col, row - col + 1);
// Initialize our glasses, the first glass initially holds all the
// water, and the remaining glasses hold none.
std::vector<double> scratch(col, 0.0);
scratch[0] = water;
// Loop through our glasses, careful to note all of our min/max'es, these could
// be replaced by if checks if one so chose to avoid the extra multiplication.
for (int i = 1; i < row; i++)
{
for (int j = min(i, col - 1); j > 0; j--)
{
scratch[j] = max((scratch[j] - capacity) / 2, 0) + max((scratch[j-1] - capacity) / 2, 0);
}
scratch[0] = max((scratch[0] - capacity) / 2, 0);
}
return min(scratch[col - 1], 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment