Pen Distribution Problem

• Difficulty Level : Hard
• Last Updated : 03 May, 2021

Given an integer N denoting the number of boxes in a pen, and two players P1 and P2 playing a game of distributing N pens among themselves as per the following rules:

• P1 makes the first move by taking 2X pens. (Initially, X = 0)
• P2 takes 3X pens.
• Value of X increases by 1 after each move.
• P1 and P2 makes move alternatively.
• If the current player has to take more pens than the number of pens remaining in the box, then they quit.
• The game will be over when both the players quit or when the box becomes empty.

The task to print the following details once the game is over:

1. The number of pens remaining in the box.
2. The number of pens collected by P1.
3. The number of pens collected by P2.

Examples:

Input: N = 22
Output:
Number of pens remaining in the box: 14
Number of pens collected by P1 : 5
Number of pens collected by P2 : 3
Explanation:

• Move 1: X = 0, P1 takes 1 pen from the box. Therefore, N = 22 – 1 = 21.
• Move 2: X = 1, P2 takes 3 pens from the box. Therefore, N = 21 – 3 = 18.
• Move 3: X = 2, P1 takes 4 pens from the box. Therefore, N = 18 – 4 = 14.
• Move 4: X = 3, P2 quits as 27 > 14.
• Move 5: X = 4, P1 quits as 16 > 14.
• Game Over! Both players have quit.

Input: N = 1
Output:
Number of pens remaining in the box : 0
Number of pens collected by P1 : 1
Number of pens collected by P2 : 0

Approach: The idea is to use Recursion. Follow the steps to solve the problem:

1. Define a recursive function:

Game_Move(N, P1, P2, X, Move, QuitP1, QuitP2)
where,
N : Total number of Pens
P1 : Score of P1
P2 : Score of P2
X : Initialized to zero
Move = 0 : P1’s turn
Move = 1 : P2’s turn
QuitP1 : Has P1 quit
QuitP2 : Has P2 quit

2. Finally, print the final values after the game has ended

Below is the implementation of the above-mentioned approach:

C++

 // C++ implementation of the// above approach #include using namespace std; // N = Total number of Pens// P1 : Score of P1// P2 : Score of P2// X : Initialized to zero// Move = 0 : P1's turn// Move = 1 : P2's turn// QuitP1 : Has P1 quit// QuitP2 : Has P2 quit // Recursive function to play Gamevoid solve(int& N, int& P1, int& P2, int& X, bool Move,           bool QuitP1, bool QuitP2){    if (N == 0 or (QuitP1 and QuitP2)) {         // Box is empty, Game Over! or        // Both have quit, Game Over!        cout << "Number of pens remaining"             << " in the box: " << N << endl;        cout << "Number of pens collected"             << " by P1: " << P1 << endl;        cout << "Number of pens collected"             << " by P2: " << P2 << endl;        return;    }     if (Move == 0 and QuitP1 == false) {         // P1 moves        int req_P1 = pow(2, X);         if (req_P1 <= N) {            P1 += req_P1;            N -= req_P1;        }        else {            QuitP1 = true;        }    }     else if (Move == 1 and QuitP2 == false) {         // P2 moves        int req_P2 = pow(3, X);         if (req_P2 <= N) {            P2 += req_P2;            N -= req_P2;        }        else {            QuitP2 = true;        }    }     // Increment X    X++;     // Switch moves between P1 and P2    Move = ((Move == 1) ? 0 : 1);     solve(N, P1, P2, X, Move, QuitP1, QuitP2);} // Function to find the number of// pens remaining in the box and// calculate score for each playervoid PenGame(int N){    // Score of P1    int P1 = 0;     // Score of P2    int P2 = 0;     // Initialized to zero    int X = 0;     // Move = 0, P1's turn    // Move = 1, P2's turn    bool Move = 0;     // Has P1 quit    bool QuitP1 = 0;     // Has P2 quit    bool QuitP2 = 0;     // Recursively continue the game    solve(N, P1, P2, X, Move,          QuitP1, QuitP2);} // Driver Codeint main(){    int N = 22;    PenGame(N);     return 0;}

Java

 // Java implementation of the// above approachimport java.util.*;import java.lang.*;public class GFG{   // N = Total number of Pens  // P1 : Score of P1  // P2 : Score of P2  // X : Initialized to zero  // Move = 0 : P1's turn  // Move = 1 : P2's turn  // QuitP1 : Has P1 quit  // QuitP2 : Has P2 quit   // Recursive function to play Game  static void solve(int N, int P1, int P2, int X,                    int Move, boolean QuitP1, boolean QuitP2)  {    if (N == 0 || (QuitP1 && QuitP2))    {       // Box is empty, Game Over! or      // Both have quit, Game Over!      System.out.println("Number of pens remaining"                         + " in the box: " + N);      System.out.println("Number of pens collected"                         + " by P1: " + P1);      System.out.println("Number of pens collected"                         + " by P2: " + P2);      return;    }    if (Move == 0 && QuitP1 == false)    {       // P1 moves      int req_P1 = (int)(Math.pow(2, X));      if (req_P1 <= N)      {        P1 += req_P1;        N -= req_P1;      }      else      {        QuitP1 = true;      }    }    else if (Move == 1 && QuitP2 == false)    {       // P2 moves      int req_P2 = (int)(Math.pow(3, X));      if (req_P2 <= N)      {        P2 += req_P2;        N -= req_P2;      }      else      {        QuitP2 = true;      }    }     // Increment X    X++;     // Switch moves between P1 and P2    Move = ((Move == 1) ? 0 : 1);    solve(N, P1, P2, X, Move, QuitP1, QuitP2);  }   // Function to find the number of  // pens remaining in the box and  // calculate score for each player  static void PenGame(int N)  {     // Score of P1    int P1 = 0;     // Score of P2    int P2 = 0;     // Initialized to zero    int X = 0;     // Move = 0, P1's turn    // Move = 1, P2's turn    int Move = 0;     // Has P1 quit    boolean QuitP1 = false;     // Has P2 quit    boolean QuitP2 = false;     // Recursively continue the game    solve(N, P1, P2, X, Move, QuitP1, QuitP2);  }   // Driver Code  public static void main (String[] args)  {    int N = 22;    PenGame(N);  }} // This code is contributed by jana_sayantan.

Python3

 # Python3 implementation of the# above approach # N = Total number of Pens# P1 : Score of P1# P2 : Score of P2# X : Initialized to zero# Move = 0 : P1's turn# Move = 1 : P2's turn# QuitP1 : Has P1 quit# QuitP2 : Has P2 quit # Recursive function to play Gamedef solve(N, P1, P2, X, Move,          QuitP1, QuitP2):     if (N == 0 or (QuitP1 and QuitP2)):         # Box is empty, Game Over! or        # Both have quit, Game Over!        print("Number of pens remaining in the box: ", N)        print("Number of pens collected by P1: ", P1)        print("Number of pens collected by P2: ", P2)        return    if (Move == 0 and QuitP1 == False):         # P1 moves        req_P1 = int(pow(2, X))         if (req_P1 <= N):            P1 += req_P1            N -= req_P1        else:            QuitP1 = True    elif (Move == 1 and QuitP2 == False):         # P2 moves        req_P2 = int(pow(3, X))        if (req_P2 <= N):            P2 += req_P2            N -= req_P2        else:            QuitP2 = True     # Increment X    X += 1     # Switch moves between P1 and P2    if(Move == 1):        Move = 0    else:        Move = 1    solve(N, P1, P2, X, Move, QuitP1, QuitP2) # Function to find the number of# pens remaining in the box and# calculate score for each playerdef PenGame(N):     # Score of P1    P1 = 0     # Score of P2    P2 = 0     # Initialized to zero    X = 0     # Move = 0, P1's turn    # Move = 1, P2's turn    Move = False     # Has P1 quit    QuitP1 = False     # Has P2 quit    QuitP2 = False     # Recursively continue the game    solve(N, P1, P2, X, Move,          QuitP1, QuitP2) # Driver CodeN = 22PenGame(N) # This code is contributed by Dharanendra L V.

C#

 // C# implementation of the// above approachusing System;class GFG {     // N = Total number of Pens    // P1 : Score of P1    // P2 : Score of P2    // X : Initialized to zero    // Move = 0 : P1's turn    // Move = 1 : P2's turn    // QuitP1 : Has P1 quit    // QuitP2 : Has P2 quit     // Recursive function to play Game    static void solve(int N, int P1, int P2, int X,                      int Move, bool QuitP1, bool QuitP2)    {        if (N == 0 || (QuitP1 && QuitP2)) {             // Box is empty, Game Over! or            // Both have quit, Game Over!            Console.WriteLine("Number of pens remaining"                              + " in the box: " + N);            Console.WriteLine("Number of pens collected"                              + " by P1: " + P1);            Console.WriteLine("Number of pens collected"                              + " by P2: " + P2);            return;        }         if (Move == 0 && QuitP1 == false) {             // P1 moves            int req_P1 = (int)(Math.Pow(2, X));             if (req_P1 <= N) {                P1 += req_P1;                N -= req_P1;            }            else {                QuitP1 = true;            }        }         else if (Move == 1 && QuitP2 == false)        {             // P2 moves            int req_P2 = (int)(Math.Pow(3, X));             if (req_P2 <= N)            {                P2 += req_P2;                N -= req_P2;            }            else            {                QuitP2 = true;            }        }         // Increment X        X++;         // Switch moves between P1 and P2        Move = ((Move == 1) ? 0 : 1);        solve(N, P1, P2, X, Move, QuitP1, QuitP2);    }     // Function to find the number of    // pens remaining in the box and    // calculate score for each player    static void PenGame(int N)    {        // Score of P1        int P1 = 0;         // Score of P2        int P2 = 0;         // Initialized to zero        int X = 0;         // Move = 0, P1's turn        // Move = 1, P2's turn        int Move = 0;         // Has P1 quit        bool QuitP1 = false;         // Has P2 quit        bool QuitP2 = false;         // Recursively continue the game        solve(N, P1, P2, X, Move, QuitP1, QuitP2);    }     // Driver Code    public static void Main()    {        int N = 22;        PenGame(N);    }} // This code is contributed by chitranayal.

Javascript



Output:
Number of pens remaining in the box: 14
Number of pens collected by P1: 5
Number of pens collected by P2: 3

Time Complexity: O(Log(N))
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up