Open In App

Minimum number of days to debug all programs

Improve
Improve
Like Article
Like
Save
Share
Report

Given N program codes and their respective debugging times in an array codeTime and an integer WorkingSessionTime, the ith program takes codeTime[i] hours to finish. WorkingSessionTime defines a threshold time, you work for at most WorkingSessionTime consecutive hours and then take a break. If WorkingSessionTime is less than 6 hours then 2 working sessions per day can be taken else only one working session per day can be taken.

Debugging should be finished following the below conditions:

  • One debugging sequence should be completed in the same session (in any order).
  • The new debugging task can be started immediately after finishing the previous one.

The task is to print the minimum number of days needed to debug all the programs following the conditions above. Assume that WorkingSessionTime is greater than or equal to the maximum element in codeTime array. 

Examples :

Input: codeTime[] = {1, 2, 3}, WorkingSessionTime = 3
Output: 1
Explanation: In first work session we will finish first and second task in 1+2 = 3 hours and we can finish last task in second work session, so the total 2 work session required to finish the task. WorkingSessionTime is less than 6 so we can take two session per day so minimum number of days  will be 1

Input: codeTime [] = {1, 2, 3, 1, 1, 3},  WorkingSessionTime = 4
Output: 2
Explanation : In first work session we will finish first and third task in 1+3 = 4 hours and in second session we can finish fourth and sixth tasks in 1+3 = 4 hours and in third session we can finish second and fifth tasks 2 + 1 = 3 hours. WorkingSessionTime is less than 6 so we can take two session per day . On first day we will take two working sessions and on next day we will take one working session. So minimum number of days required is 2

 

Approach:  A simple solution is to try all possible orders of tasks. Start by picking the first element  from the array, marking it as visited and recurse for remaining tasks and find out minimum sessions among all possible orders It is basically a backtracking based solution. After finding a minimum number of sessions we will check if the working hours of the session are less than 6 or not. If it is less than 6 then we will further check no of the minimum sessions are even or odd. 
 

Optimal Approach: A better solution is to use Bitmasking and DP

The idea is to use the fact that there are up to 14 tasks, So we can use a integer variable as mask to denote which elements are processed. if the ith bit is off, it means the ith task is yet to be processed with the remaining time we have for the current session. If the ith bit is set, it means the ith program code debugging task is processed.

  • Initialize mask as 000…000, which represents the initial (unprocessed) states of all elements.
  • Pass remaining time as 0, which means there is no remaining time for the current session and we have to create a new session.
  • Check if the ith bit is processed or not, make calls if the task is unprocessed. if ith program code debugging task is unprocessed, mark it as processed.
  • If the remaining time is greater than the codeTime[i], we will include ith program code debugging task in the current session and update the remaining time, else we have to create new session and increase the number of sessions by 1.
  • Once all the elements are processed or the mask becomes 1, we will get the minimum possible sessions.
  • If working session time is less than 6, we will further check a minimum number of possible sessions is even or odd if it even a minimum number of days will be half of the minimum number of sessions and if it is the odd minimum number of days half of the minimum number of sessions +1, else a minimum number of days will be equal to answer.

To deal with the overlapping subproblems, create a 2D DP table to store the answers for subproblems. For every element dp[i][j], i is the mask and j is the remaining time.

Below is the implementation of the above approach:

C++14




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate
// the minimum work sessions
int minSessions(vector<int>& codeTime,
                vector<vector<int> >& dp,
                int ones, int n,
                int mask, int currTime,
                int WorkingSessionTime)
{
    // Break condition
    if (currTime > WorkingSessionTime)
        return INT_MAX;
 
    // All bits are set
    if (mask == ones)
        return 1;
 
    // Check if already calculated
    if (dp[mask][currTime] != -1)
        return dp[mask][currTime];
 
    // Store the answer
    int ans = INT_MAX;
    for (int i = 0; i < n; i++) {
        // Check if ith bit is set or unset
        if ((mask & (1 << i)) == 0) {
 
            // Including in current work session
            int inc = minSessions(
                codeTime, dp, ones,
                n, mask | (1 << i),
                currTime + codeTime[i],
                WorkingSessionTime);
 
            // Including in next work session
            int inc_next
                = 1
                  + minSessions(
                        codeTime, dp, ones, n,
                        mask | (1 << i), codeTime[i],
                        WorkingSessionTime);
 
            // Resultant answer will be minimum of both
            ans = min({ ans, inc, inc_next });
        }
    }
    return dp[mask][currTime] = ans;
}
 
// Function to initialize DP array
// and solve the problem
int solve(vector<int> codeTime, int n,
          int WorkingSessionTime)
{
 
    // Initialize dp table with -1
    vector<vector<int> > dp((1 << 14),
                            vector<int>(15, -1));
 
    // Resultant mask
    int ones = (1 << n) - 1;
 
    int ans = minSessions(codeTime, dp,
                          ones, n, 0, 0,
                          WorkingSessionTime);
 
    // no. of minimum work sessions is even
    if (WorkingSessionTime < 6) {
        if (ans % 2 == 0)
            ans = ans / 2;
 
        // no. of minimum work sessions is odd
        else
            ans = (ans / 2) + 1;
    }
 
    return ans;
}
 
// Driver code
int main()
{
    vector<int> codeTime = { 1, 2, 3, 1, 1, 3 };
    int n = codeTime.size();
 
    int WorkingSessionTime = 4;
 
    cout
        << solve(codeTime, n, WorkingSessionTime)
        << endl;
    return 0;
}


Java




// Java program for the above approach
import java.util.Arrays;
 
class GFG
{
 
    // Function to calculate
    // the minimum work sessions
    public static int minSessions(int[] codeTime, int[][] dp,
                                  int ones, int n, int mask,
                                  int currTime,
                                  int WorkingSessionTime)
     
    {
        // Break condition
        if (currTime > WorkingSessionTime)
            return Integer.MAX_VALUE;
 
        // All bits are set
        if (mask == ones)
            return 1;
 
        // Check if already calculated
        if (dp[mask][currTime] != -1)
            return dp[mask][currTime];
 
        // Store the answer
        int ans = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            // Check if ith bit is set or unset
            if ((mask & (1 << i)) == 0) {
 
                // Including in current work session
                int inc = minSessions(codeTime, dp, ones, n,
                                      mask | (1 << i), currTime +
                                      codeTime[i], WorkingSessionTime);
 
                // Including in next work session
                int inc_next = 1 + minSessions(codeTime, dp,
                                               ones, n, mask | (1 << i),
                                               codeTime[i], WorkingSessionTime);
 
                // Resultant answer will be minimum of both
                ans = Math.min(ans, Math.min(inc, inc_next));
            }
        }
        return dp[mask][currTime] = ans;
    }
 
    // Function to initialize DP array
    // and solve the problem
    public static int solve(int[] codeTime, int n,
                            int WorkingSessionTime)
    {
 
        // Initialize dp table with -1
        int[][] dp = new int[(1 << 14)][];
 
        for (int i = 0; i < 1 << 14; i++) {
            dp[i] = new int[15];
            Arrays.fill(dp[i], -1);
        }
       
        // Resultant mask
        int ones = (1 << n) - 1;
        int ans = minSessions(codeTime, dp,
                              ones, n, 0, 0,
                              WorkingSessionTime);
 
        // no. of minimum work sessions is even
        if (WorkingSessionTime < 6)
        {
            if (ans % 2 == 0)
                ans = ans / 2;
 
            // no. of minimum work sessions is odd
            else
                ans = (ans / 2) + 1;
        }
 
        return ans;
    }
 
    // Driver code
    public static void main(String args[]) {
        int[] codeTime = { 1, 2, 3, 1, 1, 3 };
        int n = codeTime.length;
 
        int WorkingSessionTime = 4;
 
        System.out.println(solve(codeTime, n, WorkingSessionTime));
    }
}
 
// This code is contributed by saurabh_jaiswal.


Python3




# Python 3 program for the above approach
import sys
 
# Function to calculate
# the minimum work sessions
def minSessions(codeTime, dp, ones, n, mask, currTime, WorkingSessionTime):
   
    # Break condition
    if (currTime > WorkingSessionTime):
        return sys.maxsize
 
    # All bits are set
    if (mask == ones):
        return 1
 
    # Check if already calculated
    if (dp[mask][currTime] != -1):
        return dp[mask][currTime]
 
    # Store the answer
    ans = sys.maxsize
    for i in range(n):
       
        # Check if ith bit is set or unset
        if ((mask & (1 << i)) == 0):
 
            # Including in current work session
            inc = minSessions(codeTime, dp, ones, n, mask | (1 << i),currTime + codeTime[i],WorkingSessionTime)
 
            # Including in next work session
            inc_next = 1 + minSessions(codeTime, dp, ones, n,mask | (1 << i), codeTime[i],WorkingSessionTime)
 
            # Resultant answer will be minimum of both
            ans = min([ans, inc, inc_next])
    dp[mask][currTime] = ans
    return ans
 
# Function to initialize DP array
# and solve the problem
def solve(codeTime, n, WorkingSessionTime):
   
    # Initialize dp table with -1
    dp = [[-1 for i in range(15)] for j in range(1 << 14)]
 
    # Resultant mask
    ones = (1 << n) - 1
 
    ans = minSessions(codeTime, dp, ones, n, 0, 0, WorkingSessionTime)
 
    # no. of minimum work sessions is even
    if (WorkingSessionTime < 6):
        if (ans % 2 == 0):
            ans = ans // 2
 
        # no. of minimum work sessions is odd
        else:
            ans = (ans / 2) + 1
 
    return int(ans)
 
# Driver code
if __name__ == '__main__':
    codeTime = [1, 2, 3, 1, 1, 3]
    n = len(codeTime)
 
    WorkingSessionTime = 4
    print(solve(codeTime, n, WorkingSessionTime))
     
    # This code is contributed by SURENDRA_GANGWAR.


C#




// C# program for the above approach
using System;
public class GFG
{
     
      // Function to calculate
    // the minimum work sessions
    public static int minSessions(int[] codeTime, int[, ] dp,
                                  int ones, int n, int mask,
                                  int currTime,
                                  int WorkingSessionTime)
     
    {
       
        // Break condition
        if (currTime > WorkingSessionTime)
            return Int32.MaxValue;
 
        // All bits are set
        if (mask == ones)
            return 1;
 
        // Check if already calculated
        if (dp[mask, currTime] != -1)
            return dp[mask, currTime];
 
        // Store the answer
        int ans = Int32.MaxValue;
        for (int i = 0; i < n; i++) {
            // Check if ith bit is set or unset
            if ((mask & (1 << i)) == 0) {
 
                // Including in current work session
                int inc = minSessions(codeTime, dp, ones, n,
                                      mask | (1 << i), currTime +
                                      codeTime[i], WorkingSessionTime);
 
                // Including in next work session
                int inc_next = 1 + minSessions(codeTime, dp,
                                               ones, n, mask | (1 << i),
                                               codeTime[i], WorkingSessionTime);
 
                // Resultant answer will be minimum of both
                ans = Math.Min(ans, Math.Min(inc, inc_next));
            }
        }
        return dp[mask, currTime] = ans;
    }
 
    // Function to initialize DP array
    // and solve the problem
    public static int solve(int[] codeTime, int n,
                            int WorkingSessionTime)
    {
 
        // Initialize dp table with -1
        int[, ] dp = new int[(1 << 14), 15];
 
        for (int i = 0; i < 1 << 14; i++) {
           
            for(int j = 0; j < 15; j++) {
                  
              dp[i, j] = -1;
            }
        }
       
        // Resultant mask
        int ones = (1 << n) - 1;
        int ans = minSessions(codeTime, dp,
                              ones, n, 0, 0,
                              WorkingSessionTime);
 
        // no. of minimum work sessions is even
        if (WorkingSessionTime < 6)
        {
            if (ans % 2 == 0)
                ans = ans / 2;
 
            // no. of minimum work sessions is odd
            else
                ans = (ans / 2) + 1;
        }
 
        return ans;
    }
 
    // Driver code
    static public void Main (){
 
           int[] codeTime = { 1, 2, 3, 1, 1, 3 };
        int n = codeTime.Length;
        int WorkingSessionTime = 4;
        Console.WriteLine(solve(codeTime, n, WorkingSessionTime));
    }
}
 
// This code is contributed by Dharanendra L V.


Javascript




<script>
       // JavaScript Program to implement
       // the above approach
 
       // Function to calculate
       // the minimum work sessions
       function minSessions(codeTime,
           dp, ones, n, mask, currTime,
           WorkingSessionTime)
       {
        
           // Break condition
           if (currTime > WorkingSessionTime)
               return Number.MAX_VALUE;
 
           // All bits are set
           if (mask == ones)
               return 1;
 
           // Check if already calculated
           if (dp[mask][currTime] != -1)
               return dp[mask][currTime];
 
           // Store the answer
           let ans = Number.MAX_VALUE;
           for (let i = 0; i < n; i++)
           {
            
               // Check if ith bit is set or unset
               if ((mask & (1 << i)) == 0)
               {
 
                   // Including in current work session
                   let inc = minSessions(
                       codeTime, dp, ones,
                       n, mask | (1 << i),
                       currTime + codeTime[i],
                       WorkingSessionTime);
 
                   // Including in next work session
                   let inc_next = 1 + minSessions(
                           codeTime, dp, ones, n,
                           mask | (1 << i), codeTime[i],
                           WorkingSessionTime);
 
                   // Resultant answer will be minimum of both
                   ans = Math.min(ans, Math.min(inc, inc_next));
               }
           }
           return dp[mask][currTime] = ans;
       }
 
       // Function to initialize DP array
       // and solve the problem
       function solve(codeTime, n,
           WorkingSessionTime) {
 
           // Initialize dp table with -1
           let dp = new Array(1 << 14);
 
           for (let i = 0; i < dp.length; i++) {
               dp[i] = new Array(15).fill(-1);
           }
 
 
           // Resultant mask
           let ones = (1 << n) - 1;
 
           let ans = minSessions(codeTime, dp,
               ones, n, 0, 0,
               WorkingSessionTime);
 
           // no. of minimum work sessions is even
           if (WorkingSessionTime < 6) {
               if (ans % 2 == 0)
                   ans = Math.floor(ans / 2);
 
               // no. of minimum work sessions is odd
               else
                   ans = Math.floor(ans / 2) + 1;
           }
 
           return ans;
       }
 
       // Driver code
       let codeTime = [1, 2, 3, 1, 1, 3];
       let n = codeTime.length;
 
       let WorkingSessionTime = 4;
 
       document.write(
           solve(codeTime, n, WorkingSessionTime))
 
    // This code is contributed by Potta Lokesh
 
   </script>


Output: 

2

 

 Time Complexity:  O(2^N * WorkingSessionTime * N), Here N is the length of array codeTime.
Auxiliary Space: O(2^N * WorkingSessionTime), size of the dp table.



Last Updated : 21 Oct, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads