There is a special kind of apple tree that grows apples every day for n days. On the ith day, the tree grows apples[i] apples that will rot after days[i] days, that is on day i + days[i] the apples will be rotten and cannot be eaten. On some days, the apple tree does not grow any apples, which are denoted by apples[i] == 0 and days[i] == 0.

You decided to eat at most one apple a day (to keep the doctors away). Note that you can keep eating after the first n days.

Given two integer arrays days and apples of length n, return the maximum number of apples you can eat.

&nbsp;
Example 1:

Input: apples = [1,2,3,5,2], days = [3,2,1,4,2]
Output: 7
Explanation: You can eat 7 apples:
- On the first day, you eat an apple that grew on the first day.
- On the second day, you eat an apple that grew on the second day.
- On the third day, you eat an apple that grew on the second day. After this day, the apples that grew on the third day rot.
- On the fourth to the seventh days, you eat apples that grew on the fourth day.


Example 2:

Input: apples = [3,0,0,0,0,2], days = [3,0,0,0,0,2]
Output: 5
Explanation: You can eat 5 apples:
- On the first to the third day you eat apples that grew on the first day.
- Do nothing on the fouth and fifth days.
- On the sixth and seventh days you eat apples that grew on the sixth day.


&nbsp;
Constraints:


	n == apples.length == days.length
	1 &lt;= n &lt;= 2 * 104
	0 &lt;= apples[i], days[i] &lt;= 2 * 104
	days[i] = 0 if and only if apples[i] = 0.


import heapq
class Solution(object):
    def eatenApples(self, apples, days):
        """
        :type apples: List[int]
        :type days: List[int]
        :rtype: int
        """
        heap = [(days[0], apples[0])]
        heapq.heapify(heap)
        day = 0
        rtn = 0
        while heap or day < len(days):
            # print(heap, day)
            apple = 0
            if heap :
                cnt, apple = heapq.heappop(heap)
                while heap and cnt <= day and apple > 0:
                    cnt, apple = heapq.heappop(heap)
            if apple > 0 and cnt > day  :
                rtn +=1
            day +=1
            if apple >  1 and cnt > day:
                heapq.heappush(heap, (cnt, apple-1))
            if day < len(days) and apples[day] > 0 :
                heapq.heappush(heap, (day +days[day], apples[day]))
        return rtn 
class Solution {
    public int eatenApples(int[] apples, int[] days) {
        PriorityQueue<Apple> minHeap = new PriorityQueue<Apple>((a, b) -> (a.validDay - b.validDay));
        
        //start from day 1
        int currentDay = 1;
        int eatenAppleCount = 0;
        
        for(int i = 0; i < apples.length; i++){
            
            //add apple count and their valid day
            if(apples[i] > 0 && days[i] > 0) {
                
                //current day is included
                int validDay = currentDay + days[i] - 1;
                
                minHeap.add(new Apple(apples[i], validDay));
            }

            
            //check for eatable apple
            while(!minHeap.isEmpty()){
                //get that applen, with minimum valid date (going to expiry soon)
                Apple apple = minHeap.remove();
                
                if(apple.validDay >= currentDay){
                    //eat 1 apple
                    apple.count--;
                    
                    //increment count
                    eatenAppleCount++;

                    //add remaiing apple, if not gonna expiry current day
                    if(apple.count > 0 && apple.validDay > currentDay){
                        minHeap.add(apple);
                    }
                    
                    break;
                }
            }
           
            //move to the next day
            currentDay++;
        }
        
        
        //eat stored apple
        while(!minHeap.isEmpty()){
            Apple apple = minHeap.remove();

            if(apple.validDay >= currentDay){
                //eat 1 apple
                apple.count--;
                
                //increment count
                eatenAppleCount++;
                
                //add remaiing apple, if not gonna expiry current day
                if(apple.count > 0 && apple.validDay > currentDay){
                    minHeap.add(apple);
                }
                
                //apple is eaten in current day, now move to next day
                currentDay++;
            }
        }
        
        
        return eatenAppleCount;
    }
}


class Apple {
    int count;
    int validDay;
    
    public Apple(int count, int validDay){
        this.count = count;
        this.validDay = validDay;
    }
}
class Solution {
public:
    int eatenApples(vector<int>& apples, vector<int>& days) {
        ios_base::sync_with_stdio(0);cin.tie(0);
        priority_queue<int,vector<int>,greater<int>>p;
        unordered_map<int,int>m;
        int ans=0;
        int i=0;
        while(p.size() || i<days.size()){
            if(i<days.size() && apples[i]!=0 && days[i]!=0){
                m[days[i]+i]=apples[i];
                p.push(days[i]+i);
            }
            while(p.size()){
                if(m[p.top()]!=0 && p.top()>i)
                    break;
                p.pop();
            }
            if(p.size()){
                ans++;
                m[p.top()]--;
            }
            ++i;
        }
        return ans;
    }
};
var eatenApples = function(apples, days) {
    const heap = new MinPriorityQueue({priority: x => x[0]});
    let totalApple = 0;
    
    for(let i = 0; i < apples.length; i++) {
        heap.enqueue([i + days[i], apples[i]]);
        
        while(!heap.isEmpty()) {
            const [expire, count] = heap.front().element;
            if(!count || expire <= i) heap.dequeue();
            else break;
        }
        
        if(heap.isEmpty()) continue;
        totalApple++;
        heap.front().element[1]--;
    }
    
    let i = apples.length;
    
    while(!heap.isEmpty()) {
        const [expire, count] = heap.dequeue().element;
        if(!count || expire <= i) continue;
        totalApple += Math.min(count, expire - i);
        i = Math.min(expire, i + count);
    }
    return totalApple;
};
Maximum Number of Eaten Apples