Program to find amount of water in a given glass
Last Updated : 12 Dec, 2024
There is a stack of water glasses in the form of a Pascal triangle and a person wants to pour the water at the topmost glass, but the capacity of each glass is 1 unit. Overflow occurs in such a way that after 1 unit, 1/2 of the remaining unit gets into the bottom left glass and the other half in the bottom right glass. We pour k units of water into the topmost glass. The task is to find how much water is there in the c'th glass of the r'th row.
Note: Assume that there are enough glasses in the triangle till no glass overflows.
Example:
Input: k = 3, r = 2, c = 1
Output: 1.000000
Explanation: After the first glass, 2 units of water will remain and they will spread equally on the two glasses on the second row. Therefore, the glass on the 2nd row and 1st column will have 1 unit of water.
Input: k = 2, r = 2, c = 2
Output: 0.5
Explanation: After the first glass, 1 units of water will remain and they will spread equally on the two glasses on the second row. Therefore, the glass on the 2nd row and 2nd column will have half unit of water.
Using Dynamic Programming - O(r^2) time and O(r^2) Space
The approach to solving the water overflow problem involves simulating water distribution through a grid-based representation of a Pascal triangle of glasses. The process starts by pouring a given amount of water into the top glass. Then, for each glass, the algorithm checks if the water exceeds the glass's capacity of 1 unit. If overflow occurs, the excess water is evenly distributed to the two glasses directly below. Each glass is capped at a maximum of 1 unit. This process is repeated iteratively until the target row is reached. The final result is the amount of water in the specified glass, ensuring no glass exceeds its maximum capacity.
C++ // C++ program to find amount // of water in a given glass Using Dynamic Programming #include <bits/stdc++.h> using namespace std; double waterOverflow(int k, int r, int c) { // DP matrix to simulate water flow in glasses vector<vector<double>> memo(r, vector<double>(r, 0.0)); // Initial water in top glass memo[0][0] = k; // Simulate water flow through triangle for (int row = 0; row < r - 1; row++) { for (int col = 0; col <= row; col++) { // Calculate water overflow double excess = max(0.0, memo[row][col] - 1.0); // Distribute excess water if (excess > 0) { // Cap current glass memo[row][col] = 1.0; // Flow to bottom glasses memo[row + 1][col] += excess / 2.0; memo[row + 1][col + 1] += excess / 2.0; } } } // Return water in target glass return min(1.0, memo[r - 1][c - 1]); } int main() { int k = 3; int r = 2; int c = 1; double waterAmount = waterOverflow(k, r, c); cout << waterAmount << endl; return 0; }
Java // Java program to find amount // of water in a given glass Using Dynamic Programming import java.util.*; class GfG { static double waterOverflow(int k, int r, int c) { // DP matrix to simulate water flow in glasses double[][] memo = new double[r][r]; // Initial water in top glass memo[0][0] = k; // Simulate water flow through triangle for (int row = 0; row < r - 1; row++) { for (int col = 0; col <= row; col++) { // Calculate water overflow double excess = Math.max(0.0, memo[row][col] - 1.0); // Distribute excess water if (excess > 0) { // Cap current glass memo[row][col] = 1.0; // Flow to bottom glasses memo[row + 1][col] += excess / 2.0; memo[row + 1][col + 1] += excess / 2.0; } } } // Return water in target glass return Math.min(1.0, memo[r - 1][c - 1]); } public static void main(String[] args) { int k = 3; int r = 2; int c = 1; double waterAmount = waterOverflow(k, r, c); System.out.println(waterAmount); } }
Python # Python program to find amount # of water in a given glass Using Dynamic Programming def waterOverflow(k, r, c): # DP matrix to simulate water flow in glasses memo = [[0.0 for _ in range(r)] for _ in range(r)] # Initial water in top glass memo[0][0] = k # Simulate water flow through triangle for row in range(r - 1): for col in range(row + 1): # Calculate water overflow excess = max(0.0, memo[row][col] - 1.0) # Distribute excess water if excess > 0: # Cap current glass memo[row][col] = 1.0 # Flow to bottom glasses memo[row + 1][col] += excess / 2.0 memo[row + 1][col + 1] += excess / 2.0 # Return water in target glass return min(1.0, memo[r - 1][c - 1]) if __name__ == "__main__": k = 3 r = 2 c = 1 waterAmount = waterOverflow(k, r, c) print(waterAmount)
C# // C# program to find amount // of water in a given glass Using Dynamic Programming using System; class GfG { static double waterOverflow(int k, int r, int c) { // DP matrix to simulate water flow in glasses double[,] memo = new double[r, r]; // Initial water in top glass memo[0, 0] = k; // Simulate water flow through triangle for (int row = 0; row < r - 1; row++) { for (int col = 0; col <= row; col++) { // Calculate water overflow double excess = Math.Max(0.0, memo[row, col] - 1.0); // Distribute excess water if (excess > 0) { // Cap current glass memo[row, col] = 1.0; // Flow to bottom glasses memo[row + 1, col] += excess / 2.0; memo[row + 1, col + 1] += excess / 2.0; } } } // Return water in target glass return Math.Min(1.0, memo[r - 1, c - 1]); } static void Main(string[] args) { int k = 3; int r = 2; int c = 1; double waterAmount = waterOverflow(k, r, c); Console.WriteLine(waterAmount); } }
JavaScript // JavaScript program to find amount // of water in a given glass Using Dynamic Programming function waterOverflow(k, r, c) { // DP matrix to simulate water flow in glasses let memo = Array.from({ length: r }, () => Array(r).fill(0.0)); // Initial water in top glass memo[0][0] = k; // Simulate water flow through triangle for (let row = 0; row < r - 1; row++) { for (let col = 0; col <= row; col++) { // Calculate water overflow let excess = Math.max(0.0, memo[row][col] - 1.0); // Distribute excess water if (excess > 0) { // Cap current glass memo[row][col] = 1.0; // Flow to bottom glasses memo[row + 1][col] += excess / 2.0; memo[row + 1][col + 1] += excess / 2.0; } } } // Return water in target glass return Math.min(1.0, memo[r - 1][c - 1]); } let k = 3; let r = 2; let c = 1; console.log(waterOverflow(k, r, c));
Using Queue - O(r^2) Time and O(r) Space
The approach simulates the water overflow process using a queue to track water distribution through a Pascal triangle of glasses. The algorithm processes glasses row by row, managing overflow by distributing excess water equally to the glasses below. It ensures that no glass exceeds its 1-unit capacity, using the queue to efficiently handle water amounts and overflow at each step. The water in each glass is updated progressively, and the target glass’s water amount is returned once the process reaches the specified row and column.
C++ // C++ program to find amount // of water in a given glass using queue #include <bits/stdc++.h> using namespace std; double waterOverflow(int k, int r, int c) { r--; c--; // Initialize queue with total water units queue<double> q; q.push(1.0*k); // Variable to track overflow from previous glasses double prev = 0; // Simulate water flow row by row for (int i = 0; i <= r; i++) { // Process current row's glasses int size = q.size(); for (int j = 0; j < size; j++) { // Get current glass water amount double curr = q.front(); // Check if target glass is reached if (i == r && j == c) return min(curr, 1.0); // Reduce water in current glass curr--; q.pop(); // Calculate and distribute overflow double val = max(curr/2.0, 0.0) + prev; q.push(val); // Track overflow for next iteration prev = max(0.0, curr/2.0); } // Add previous row's overflow to next row q.push(prev); prev = 0; } return 0; } int main() { int k = 3; int r = 2; int c = 1; cout << waterOverflow(k, r, c); return 0; }
Java // Java program to find amount // of water in a given glass using queue import java.util.*; class GfG { static double waterOverflow(int k, int r, int c) { // Adjust row and column to 0-based indexing r--; c--; // Initialize queue with total water units Queue<Double> q = new LinkedList<>(); q.add(1.0 * k); // Variable to track overflow from // previous glasses double prev = 0; // Simulate water flow row by row for (int i = 0; i <= r; i++) { // Process current row's glasses int size = q.size(); for (int j = 0; j < size; j++) { // Get current glass water amount double curr = q.poll(); // Check if target glass is reached if (i == r && j == c) return Math.min(curr, 1.0); // Reduce water in current glass curr--; // Calculate and distribute overflow double val = Math.max(curr / 2.0, 0.0) + prev; q.add(val); // Track overflow for next iteration prev = Math.max(0.0, curr / 2.0); } // Add previous row's overflow to next row q.add(prev); prev = 0; } return 0; } public static void main(String[] args) { int k = 3; int r = 2; int c = 1; System.out.println(waterOverflow(k, r, c)); } }
Python # Python program to find amount # of water in a given glass using queue from collections import deque def waterOverflow(k, r, c): # Adjust row and column to 0-based indexing r -= 1 c -= 1 # Initialize queue with total water units q = deque([1.0 * k]) # Variable to track overflow from previous glasses prev = 0 # Simulate water flow row by row for i in range(r + 1): # Process current row's glasses size = len(q) for j in range(size): # Get current glass water amount curr = q.popleft() # Check if target glass is reached if i == r and j == c: return min(curr, 1.0) # Reduce water in current glass curr -= 1 # Calculate and distribute overflow val = max(curr / 2.0, 0.0) + prev q.append(val) # Track overflow for next iteration prev = max(0.0, curr / 2.0) # Add previous row's overflow to next row q.append(prev) prev = 0 return 0 if __name__ == "__main__": k = 3 r = 2 c = 1 print(waterOverflow(k, r, c))
C# // C# program to find amount // of water in a given glass using queue using System; using System.Collections.Generic; class GfG { static double waterOverflow(int k, int r, int c) { // Adjust row and column to 0-based indexing r--; c--; // Initialize queue with total water units Queue<double> q = new Queue<double>(); q.Enqueue(1.0 * k); // Variable to track overflow from previous glasses double prev = 0; // Simulate water flow row by row for (int i = 0; i <= r; i++) { // Process current row's glasses int size = q.Count; for (int j = 0; j < size; j++) { // Get current glass water amount double curr = q.Dequeue(); // Check if target glass is reached if (i == r && j == c) return Math.Min(curr, 1.0); // Reduce water in current glass curr--; // Calculate and distribute overflow double val = Math.Max(curr / 2.0, 0.0) + prev; q.Enqueue(val); // Track overflow for next iteration prev = Math.Max(0.0, curr / 2.0); } // Add previous row's overflow to next row q.Enqueue(prev); prev = 0; } return 0; } static void Main(string[] args) { int k = 3; int r = 2; int c = 1; Console.WriteLine(waterOverflow(k, r, c)); } }
JavaScript // JavaScript program to find amount // of water in a given glass using queue function waterOverflow(k, r, c) { // Adjust row and column to 0-based indexing r--; c--; // Initialize queue with total water units let q = []; q.push(1.0 * k); // Variable to track overflow from previous glasses let prev = 0; // Simulate water flow row by row for (let i = 0; i <= r; i++) { // Process current row's glasses let size = q.length; for (let j = 0; j < size; j++) { // Get current glass water amount let curr = q.shift(); // Check if target glass is reached if (i === r && j === c) return Math.min(curr, 1.0); // Reduce water in current glass curr--; // Calculate and distribute overflow let val = Math.max(curr / 2.0, 0.0) + prev; q.push(val); // Track overflow for next iteration prev = Math.max(0.0, curr / 2.0); } // Add previous row's overflow to next row q.push(prev); prev = 0; } return 0; } let k = 3; let r = 2; let c = 1; console.log(waterOverflow(k, r, c));