Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Problem Statement
3.
Example
3.1.
Input
3.2.
Output
3.3.
Explanation
4.
Native Approach for Chocolate Distribution Problem
4.1.
Algorithm
4.2.
C++ Implementation
4.2.1.
Output
4.3.
Java Implementation
4.3.1.
Output
4.4.
Complexities
4.4.1.
Time Complexity
4.4.2.
Space Complexity
5.
Efficient Approach for Chocolate Distribution Problem
5.1.
Algorithm
5.2.
Dry Run
5.3.
Implementation in C++
5.3.1.
Output
5.4.
Implementation in Java
5.4.1.
Output
5.5.
Complexities
5.5.1.
Time Complexity
5.5.2.
Space Complexity
6.
Frequently Asked Questions
6.1.
How do you solve the Chocolate Distribution Problem?
6.2.
Can the Chocolate Distribution Problem have multiple solutions?
6.3.
What is chocolate distribution problem?
6.4.
What is the channel of distribution of chocolate?
7.
Conclusion
Last Updated: Mar 27, 2024
Easy

Chocolate Distribution Problem

Author Sanjana kumari
7 upvotes

Introduction

Data Structure and Algorithm problems are some of the most complex, exciting, and skill-boosting exercises that you, as a fellow coder can perform.  

Introduction

Let's start by explaining the problem statement.

Problem Statement

The Chocolate Distribution Problem is a problem where you have a certain number of chocolate packets and must distribute them among a given number of children. 

Distribute chocolate in such a way that:

  • Each student gets at least one packet of chocolate.
Chocolate Distribution Problem
  • The difference between the maximum number of chocolate in a packet and the minimum number in a packet given to the students is minimal.
Chocolate Distribution Problem Statement

Try to solve this problem before moving on to further discussion here.

Let’s understand the problem statement through an example.

Example

Suppose we have some chocolate packets to distribute among four people. We have a chocolate array as [ 6,8,11,21,90,49 ] where each number represents the number of chocolates in the packet to be distributed.

Input

Chocolate Packets =  [ 6,8,11,21,90,49 ] 
No. of Chocolate Packets = 6 
No.of students = 4

Output

15

Explanation

Now, we calculate the differences between the maximum and minimum number of chocolates for each possible chocolate distribution. Chocolates in each packet are given as 6,8,11,21,90,49 ]. 

There are many possible combinations to distribute 4 chocolate packets to 4 students. But out of them, if we distribute 4 packets, such as (6,8,11,21), then the difference between the maximum and minimum element will be 21-6=15, and this is the minimum difference that will occur. Thus the output is 15.

Also read, Euclid GCD Algorithm

Native Approach for Chocolate Distribution Problem

The approach is to generate all possible subsets of size m from an array of n chocolates by recursively including and excluding each chocolate from the subset until the desired subset size is reached. Once all subsets are generated, we sort them and compute the minimum difference between the maximum and minimum chocolate packets.

Algorithm

Base Case:

  • If the current subset size equals m, add this subset to the 2D ArrayList.

Recursive Steps:

  • For each index, i from the current index to the end of the array, add the element at that index to the current subset and call the recursive function with the updated subset and index.
     
  • After the recursive call, remove the last element from the current subset to backtrack.
     
  • After finding all the subsets of size m, we will loop through each subset and find the difference between the maximum and minimum chocolates distributed. We will keep track of the minimum difference found so far and the chocolate distribution that resulted in that difference.
     
  • Finally, we will output the minimum difference found.

C++ Implementation

#include<iostream>
#include<climits>
#include<vector>
#include<algorithm>

using namespace std;

void generateSubsets(vector<long long>& a, int index, vector<long long> current, vector<vector<long long>>& subsets, int m) {
    //Checking for index out of bound.
    if(index == a.size()){
        
        // Base case: if current subset has size m, add it to subsets and return
        if (current.size() == m) {
            subsets.push_back(current);
            return;
        }
        return;
    }
    
    // Recursive step: generate subsets by including and excluding each element starting from index
        
    //Dont Take Current
    generateSubsets(a, index + 1, current, subsets, m);
    
    //Take Current
    current.push_back(a[index]);
    generateSubsets(a, index + 1, current, subsets, m);
    current.pop_back();
    
}
    
long long chocolateDistribution(vector<long long> a, long long n, long long m){
    vector<vector<long long>> subsets;
    vector<long long> current;
    generateSubsets(a, 0, current, subsets, m);
    long long minDiff = INT_MAX;
    vector<long long> minDist;
    
    /*
        Taking difference between maximum and minimum element from all
        possible subsets and storing the minimum difference possible.
    */
    for (auto subset : subsets) {
        sort(subset.begin(), subset.end());
        int diff = subset[m - 1] - subset[0];
        
        if (diff < minDiff) {
            minDiff = diff;
            minDist = subset;
        }
    }
    return minDiff;

} 
int main(){
    vector<long long> arr={6,8,11,21,90,49};
    int numPackets=6;
    int numStudents=4;
    int Res=chocolateDistribution(arr,numPackets,numStudents);
    
    // Print the minimum difference and the corresponding subset
    cout << "Minimum difference: " << Res << endl;
}

 

Output

Output

Java Implementation

import java.util.ArrayList;
import java.util.Arrays;


public class Main {
/*
    Recursive function to generate all subsets of size m from array a
    and store them in the subsets vector
*/

    public static void generateSubsets(int[] a, int index, ArrayList<Integer> current, ArrayList<ArrayList<Integer>> subsets, int m) {
        //Checking for index out of bound.
        if(index == a.length){
            
            // Base case: if current subset has size m, add it to subsets and return
            if (current.size() == m) {
                subsets.add(new ArrayList<>(current));
                return;
            }
            return;
        }
        
        // Recursive step: generate subsets by including and excluding each element starting from index
            
        //Dont Take Current
        generateSubsets(a, index + 1, current, subsets, m);
        
        //Take Current
        current.add(a[index]);
        generateSubsets(a, index + 1, current, subsets, m);
        current.remove(current.size() - 1);
        
    }

    public static int chocolateDistribution(int [] a, int n, int m){
        ArrayList<ArrayList<Integer>> subsets = new ArrayList<>();
        ArrayList<Integer> current = new ArrayList<>();
        generateSubsets(a, 0, current, subsets, m);

        int minDiff = Integer.MAX_VALUE;
        
        /*
            Taking difference between maximum and minimum element from all
            possible subsets and storing the minimum difference possible.
        */
        ArrayList<Integer> minDist = new ArrayList<>();
        for (ArrayList<Integer> subset : subsets) {
            // Sort the subset and compute the difference between the last and first elements
            Integer[] subsetArray = subset.toArray(new Integer[0]);
            Arrays.sort(subsetArray);
            int diff = subsetArray[m - 1] - subsetArray[0];
            if (diff < minDiff) {
                minDiff = diff;
                minDist = subset;
            }
        }
        return minDiff;
    }

    public static void main(String[] args) {
        
        // Hardcore array for testing purposes
        int[] a = {6,8,11,21,90,49};
                
        int numPackets = 6;
        int numStudents = 4;

        int Res=chocolateDistribution(a,numPackets,numStudents);

        // Print the minimum difference and the corresponding subset
        System.out.println("Minimum difference: " + Res);
    }
}

Output

Output

Complexities

Time Complexity

O((2^n) * m log m), where n is the input array's size and m is each subset's size.

Reason: The time complexity of the code is O((2^n) * m log m) because it generates all subsets of size m, sorts each subset, and iterates over all subsets.

Space Complexity

O(2^m * m), where n is the input array's size and m is each subset's size.

Reason:  The code generates all subsets of size m from an array of length n. Since there are 2^m subsets of size m, the space required to store all subsets is O(2^m * m).

Efficient Approach for Chocolate Distribution Problem

In this problem, we will sort the array first. Then we create two pointer. First at the initial position and second at the one less than the total count of people. We will then slide it at every iteration, calculate the difference between the right and left indexes, and find the minimum value.

Algorithm

Here is the step-wise algorithm for the binary search approach:

  1. Read the number of packets (n), chocolate packets, and the number of students (m) from the user.
     
  2. If the number of packets exceeds the number of students, return -1 to indicate an invalid input.
     
  3. Sort the chocolate packets in ascending order.
     
  4. Initialise a variable minDiff to infinity.
     
  5. Loop through the chocolate packets from index 0 to n - m.
     
  6. Calculate the difference between the last and first chocolate packets in the current distribution.
     
  7. If the difference is smaller than the current minimum difference, update the minimum difference to the current difference.
     
  8. Return the minimum difference.
     
  9. Print the result to the console.

Dry Run

Input: chocolates = [6,8,11,21,90,49], m = 4.

dry run

1. Sort the chocolate array: chocolates = [6,8,11,21,90,49].

After sort

2. Initialize a variable minDifference to INT_MAX.
 

3. Loop through the chocolate array from index 0 to n-m-1.
 

4. Calculate the difference between the maximum chocolate in the current subarray and the minimum chocolate in the current subarray.

  • The maximum chocolate is chocolates[i+m-1].
  • The minimum chocolate is chocolates[i].
  • Calculate the difference between these two values.

 

5. If the calculated difference is less than the current value of minDifference, update minDifference.

difference between the maximum chocolate and minimum chocolate

6. After the loop, minDifference will contain the minimum difference between the maximum and minimum number of chocolates given to m people.
 

7. If m is greater than n, return -1 to indicate an error.
 

8. Otherwise, return the value of minDifference.
 

Output: 15.

 

Implementation in C++

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <climits>
using namespace std;


/*
    This function finds the minimum difference between the maximum and minimum packets
    chosen by 'numStudents' students from a given list of 'numPackets' packets
*/
int findMinimumDifference(vector<int>& packets, int numStudents) {
    int numPackets = packets.size();
    
    // If the number of packets is less than the number of students, it is invalid
    if (numPackets < numStudents)
        return -1;
    
    // Initializing minimum difference to maximum value
    int minDifference = INT_MAX;
    
    //Sorting the packets in ascending order.
    sort(packets.begin(),packets.end());
    
    // Loop through the packets to find the minimum difference
    for (int i = 0; i <= numPackets - numStudents; i++) {
        
        // Find the maximum and minimum packets in the current window
        int maxPacket = packets[i+numStudents-1];
        int minPacket = packets[i];
        
        // Update the minimum difference if the current difference is smaller
        int difference = abs(maxPacket - minPacket);
        
        if (difference < minDifference)
            minDifference = difference;
    }
    return minDifference;
}


int main() {
    vector<int> packets = {6,8,11,21,90,49};
    int numStudents = 4;

    // Finding the minimum difference
    int minDifference = findMinimumDifference(packets, numStudents);

    // Printing the minimum difference
    if (minDifference == -1)
        cout << "Invalid input" << endl;
    else
        cout << "Minimum difference is " << minDifference << endl;

    return 0;
}

Output

Output

Implementation in Java

// Importing required packages
import java.util.Arrays;
import java.util.List;


public class Solution {
    
    /*
        This function finds the minimum difference between the maximum and minimum packets
        chosen by 'numStudents' students from a given list of 'numPackets' packets
    */
    
    public static int findMinimumDifference(int[] packets, int numStudents) {
        int numPackets = packets.length;
        
        // If the number of packets is less than the number of students, it is invalid
        if (numPackets < numStudents)
            return -1;
        
        // Initializing minimum difference to maximum value
        int minDifference = Integer.MAX_VALUE;
        
        //Sorting the packets in ascending order.
        Arrays.sort(packets);
        
        // Loop through the packets to find the minimum difference
        for (int i = 0; i <= numPackets - numStudents; i++) {
            
            // Find the maximum and minimum packets in the current window
            int maxPacket = packets[i+numStudents-1];
            int minPacket = packets[i];
            
            // Update the minimum difference if the current difference is smaller
            int difference = Math.abs(maxPacket - minPacket);
            if (difference < minDifference)
                minDifference = difference;
        }
        return minDifference;
    }
    
    public static void main(String[] args) {
        int packets[] = {6,8,11,21,90,49};
        int numStudents = 4;
        
        // Finding the minimum difference
        int minDifference = findMinimumDifference(packets, numStudents);
        
        // Printing the minimum difference
        if (minDifference == -1)
            System.out.println("Invalid input");
        else
            System.out.println("Minimum difference is " + minDifference);
    }
}

Output

Output

Complexities

Time Complexity

O(n log n), where n is the number of packets. 

Reason: The algorithm sorts the array of packets using a comparison-based sorting algorithm such as QuickSort, which has an average time complexity of O(n log n). After sorting the array, the algorithm performs a linear scan to find the minimum difference, which takes O(n) time. 

Space Complexity

O(n), where n is the number of packets.

Reason: The algorithm needs to store the packets in an array of size n, hence the O(n) space complexity.

Frequently Asked Questions

How do you solve the Chocolate Distribution Problem?

To solve the Chocolate Distribution Problem, you can sort the packets of chocolates in non-decreasing order of the number of chocolates in each packet and then distribute the packets starting from the smallest one. This ensures that each child gets at least one packet, and the difference between the maximum and minimum number of chocolates in the packets given to the children is minimised.

Can the Chocolate Distribution Problem have multiple solutions?

No, the Chocolate Distribution Problem has a unique solution, as the requirement is to minimise the difference between the maximum and minimum number of chocolates in the packets given to the children.

What is chocolate distribution problem?

The chocolate distribution problem involves distributing a limited quantity of chocolates among a group while minimizing inequalities or preferences.

What is the channel of distribution of chocolate?

Chocolates follow a distribution channel starting with manufacturers, who supply wholesalers or distributors. From there, chocolates reach retailers such as grocery stores, specialty shops, and online platforms. Ultimately, they are sold to consumers through various outlets, including vending machines, gift shops, and direct sales, forming a diverse distribution network.

Conclusion

In conclusion, the Chocolate Distribution Problem centers around optimizing the equitable allocation of chocolates to individuals with varying preferences. Typically addressed through sorting and distribution based on preferences, this problem illustrates the importance of balancing fairness and efficiency in resource allocation, often tackled through algorithms and mathematical optimization.

Here is some similar concept blog you may try:

We recommend you practice problem sets based on binary search trees to master your fundamentals. You can get a wide range of questions similar to this on Coding Ninjas Studio

Live masterclass