Skip to content
Related Articles

Related Articles

Improve Article

Predict the winner of a card game of removing K cards in each turn such that Bitwise AND of K and size of pile is 0

  • Difficulty Level : Expert
  • Last Updated : 21 Apr, 2021

There are two players A and B and a pile of N cards stacked upon each other.  The task is to find the winner of the game, assuming both players play optimally as per the following guidelines:

  • Player A always begins the game and the players take alternate turns subsequently.
  • In each turn, a player can remove K( 1 ≤ K ≤ N) cards if K & n = 0, where n is the size of the current pile.
  • If a player cannot make a move at any point in the game, then that player loses, and the game ends.

Examples:

Input: N = 1
Output: B
Explanation:
A can only remove 1 card, but 1 & 1 = 1, so A is unable to make a move.
Hence, B wins the game.

Input: N = 4
Output: A
Explanation:
A will remove 3 cards as 3 & 4 = 0, now only 1 card is left and B cannot make a move.
Hence, A wins the game.

Approach: The idea is based on the observation that if the count of 1s in the binary representation of N, before a 0 is encountered, is odd then A wins the game. If no such combination of 1s and 0s exists throughout the binary string, then B wins. Follow the steps below to solve the problem:



  • Initialize a variable countOne to store the count of 1.
  • Convert N into its binary representation and store it in a string, binString.
  • Traverse the string binString and do the following:
    • If ‘1‘ is encountered, increment the countOne.
    • If ‘0‘ is encountered, check if the countOne is odd or even, if the countOne is odd A wins, and break out of the loop, otherwise reset the countOne to 0 and continue traversing.
  • If the whole string is traversed without breaking, then B wins.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the winner of the
// game if both player plays optimally
void findWinner(int N)
{
     
    // Stores the count of 1s
    int onesBeforeZero = 0;
    int flag = 1;
     
    // Convert N to binary representation
    int binString[32];
 
    int i = 0;
     
    while (N > 0)
    {
         
        // Storing remainder in binary array
        binString[i] = N % 2;
        N = N / 2;
        i++;
    }
 
    int l = sizeof(binString) /
            sizeof(binString[0]);
 
    // Traverse the binary string
    for(int j = 0; j < l; j++)
    {
         
        // If 1 is encountered,
        // increment count of 1s
        if (binString[j] == 1)
        {
            onesBeforeZero += 1;
        }
 
        // If 0 is encountered, check
        // if count of 1s is odd
        else
        {
             
            // If count of 1s is odd,
            // then winner is A
            if (onesBeforeZero & 1)
            {
                cout << "A";
                flag = 0;
                break;
            }
 
            // If count of 1s is even,
            // reset it to 0
            else
                onesBeforeZero = 0;
        }    
    }
     
    // If entire loop is traversed
    // without breaking, then
    // B is the winner
    if (flag == 1)
        cout << "B";
}
 
// Driver Code
int main()
{
    int N = 4;
     
    // Function Call
    findWinner(N);
 
    return 0;
}
 
// This code is contributed by jana_sayantan

C




// C program for the above approach
#include <stdio.h>
 
// Function to find the winner of the
// game if both player plays optimally
void findWinner(unsigned long long N)
{
    // Stores the count of 1s
    int onesBeforeZero = 0;
    int flag = 1, j = 0;
    char binString[32];
     
    // Converting N into a binary string
    for(int i = 31; i >= 0; i--)
    {
        unsigned long long temp = N >> i;
         
        if (temp & 1)
            binString[j] = '1';
        else
            binString[j] = '0';
             
        j += 1;
    }
     
    // Traverse the binary string
    for(int i = 0; i < 32; i++)
    {
        if (binString[i] == '1')
         
            // If 1 is encountered
            // increment ones count
            onesBeforeZero += 1;
        else
        {
             
            // If 0 is encountered check
            // if ones count is odd
            if (onesBeforeZero & 1)
            {
                 
                // If ones count is odd
                // winner is A break
                printf("A");
                flag = 0;
                break;
            }
            else
                // If ones count is even
                // reset it to 0 and continue
                onesBeforeZero = 0;
        }
    }
     
    // If entire loop is traversed
    // without breaking, then
    // B is the winner
    if (flag == 1)
        printf("B");
}   
 
// Driver code
int main()
{
    unsigned long long N = 4;
     
    // Function Call
    findWinner(N);
     
    return 0;
}
 
// This code is contributed by Praneeth Kapila

Java




// Java program for the above approach
class GFG{
     
// Function to find the winner
static void findWinner(long N)
{
    // Stores the count of 1s
    int onesBeforeZero = 0, flag = 1, j = 0;
     
    String[] binString = new String[32];
     
    // Converting N into a binary string
    for(int i = 31; i >= 0; i--)
    {
        long temp = N >> i;
         
        if ((temp & 1) == 1)
            binString[j] = "1";
        else
            binString[j] = "0";
             
        j += 1;
    }
 
    for(int i = 0; i < 32; i++)
    {
        if (binString[i] == "1")
         
            // If 1 is encountered
            // increment ones count
            onesBeforeZero += 1;
        else
        {
             
            // If 0 is encountered check
            //if ones count is odd
            if ((onesBeforeZero & 1) == 1)
            {
                 
                // If ones count is odd winner
                // is A break
                System.out.println("A");
                flag = 0;
                break;
            }
            else
                // If ones count is even
                // reset it to 0 and continue
                onesBeforeZero = 0;
        }
    }
     
    // If entire loop is traversed
    // without breaking, then
    // B is the winner
    if (flag == 1)
        System.out.println("B");
}
 
// Driver code
public static void main(String[] args)
{
    long N = 4;
     
    // Function Call
    findWinner(N);
}
}
 
// This code is contributed by Praneeth Kapila

Python3




# Python3 program for the above approach
 
# Function to find the winner of the
# game if both player plays optimally
def findWinner(N):
 
    # Stores the count of 1s
    onesBeforeZero = 0
    flag = 1
 
    # Convert N to binary representation
    binString = bin(N).replace("0b", "")
 
    l = len(binString)
 
    # Traverse the binary string
    for j in range(l):
 
        # If 1 is encountered,
        # increment count of 1s
        if binString[j] == '1':
            onesBeforeZero += 1
 
        # If 0 is encountered, check
        # if count of 1s is odd
        else:
 
            # If count of 1s is odd,
            # then winner is A
            if onesBeforeZero & 1:
                print("A")
                flag = 0
                break
 
            # If count of 1s is even,
            # reset it to 0
            else:
                onesBeforeZero = 0
 
    # If entire loop is traversed
    # without breaking, then
    # B is the winner
    if flag == 1:
        print("B")
 
 
# Driver Code
N = 4
 
# Function Call
findWinner(N)

C#




// C# program for the above approach
using System;
 
class GFG{
     
// Function to find the winner
static void findWinner(long N)
{
     
    // Stores the count of 1s
    int onesBeforeZero = 0, flag = 1, j = 0;
     
    String[] binString = new String[32];
     
    // Converting N into a binary string
    for(int i = 31; i >= 0; i--)
    {
        long temp = N >> i;
         
        if ((temp & 1) == 1)
            binString[j] = "1";
        else
            binString[j] = "0";
             
        j += 1;
    }
 
    for(int i = 0; i < 32; i++)
    {
        if (binString[i] == "1")
         
            // If 1 is encountered
            // increment ones count
            onesBeforeZero += 1;
        else
        {
             
            // If 0 is encountered check
            //if ones count is odd
            if ((onesBeforeZero & 1) == 1)
            {
                 
                // If ones count is odd winner
                // is A break
                Console.WriteLine("A");
                flag = 0;
                break;
            }
            else
             
                // If ones count is even
                // reset it to 0 and continue
                onesBeforeZero = 0;
        }
    }
     
    // If entire loop is traversed
    // without breaking, then
    // B is the winner
    if (flag == 1)
        Console.WriteLine("B");
}
 
// Driver code
public static void Main(String[] args)
{
    long N = 4;
     
    // Function Call
    findWinner(N);
}
}
 
// This code is contributed by shivanisinghss2110

Javascript




<script>
 
// Javascript program for the above approach
 
// Function to find the winner
function findWinner(N)
{
      
    // Stores the count of 1s
    let onesBeforeZero = 0, flag = 1, j = 0;
      
    let binString = [];
      
    // Converting N leto a binary string
    for(let i = 31; i >= 0; i--)
    {
        let temp = N >> i;
          
        if ((temp & 1) == 1)
            binString[j] = "1";
        else
            binString[j] = "0";
              
        j += 1;
    }
  
    for(let i = 0; i < 32; i++)
    {
        if (binString[i] == "1")
          
            // If 1 is encountered
            // increment ones count
            onesBeforeZero += 1;
        else
        {
              
            // If 0 is encountered check
            //if ones count is odd
            if ((onesBeforeZero & 1) == 1)
            {
                  
                // If ones count is odd winner
                // is A break
                document.write("A");
                flag = 0;
                break;
            }
            else
              
                // If ones count is even
                // reset it to 0 and continue
                onesBeforeZero = 0;
        }
    }
      
    // If entire loop is traversed
    // without breaking, then
    // B is the winner
    if (flag == 1)
        document.write("B");
}
     
// Driver code
let N = 4;
  
// Function Call
findWinner(N);
 
// This code is contributed by code_hunt
 
</script>
Output: 
A

 

Time Complexity: O(log N)
Auxiliary Space: O(log N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :