Find winner of the game when any set bit is removed in each move
Last Updated :
11 Oct, 2023
Two players, Player 1 and Player 2, are given an integer N to play a game. The rules of the game are as follows :
- In one turn, a player can remove any set bit of N in its binary representation to make a new N.
- Player 1 always takes the first turn.
- If a player cannot make a move, he loses.
Examples:
Input: N = 8
Output: 1
Explanation: N = 8
N = 1000 (binary)
Player 1 takes the bit.
The remaining bits are all zero.
Player 2 cannot make a move,
so Player 1 wins.
Input: N = 3
Output: 2
Approach: The given problem can be solved by following the below idea:
Calculate the number of set bits in N. If the number of set bits is odd then player 1 will always win [because he will take the following turns - 1st, 3rd, 5th, . . . and any odd turn]. Otherwise, player 2 will win the game.
Follow the steps mentioned below to implement the:
- Calculate the number of set bits in N.
- If the number of the set bits is odd then player 1 wins.
- Else, player 2 wins.
Below is the implementation of the above approach.
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to find the winner
int swapBitGame(long long N)
{
int bitCount = 0;
// Calculate the number of set bit in
// N using Brian Kernighan's Algorithm
while (N) {
N = (N & (N - 1));
bitCount++;
}
// If bitCount is even return 2
// else return 1
return bitCount % 2 == 0 ? 2 : 1;
}
// Driver Code
int main()
{
long long N = 8;
// Function Call
cout << swapBitGame(N) << endl;
return 0;
}
Java
// Java code to implement the approach
import java.io.*;
class GFG {
// Function to find the winner
static int swapBitGame(long N)
{
int bitCount = 0;
// Calculate the number of set bit in
// N using Brian Kernighan's Algorithm
while (N!=0) {
N = (N & (N - 1));
bitCount++;
}
// If bitCount is even return 2
// else return 1
return bitCount % 2 == 0 ? 2 : 1;
}
public static void main(String[] args)
{
long N = 8;
// Function call
System.out.println(swapBitGame(N));
}
}
// This code is contributed by lokeshmvs21.
Python
# Python code to implement the approach
# Function to find the winner
def swapBitGame(N):
bitCount = 0
# Calculate the number of set bit in
# N using Brian Kernighan's Algorithm
while (N > 0):
N = (N & (N - 1))
bitCount += 1
# If bitCount is even return 2
# else return 1
return (2) if bitCount % 2 == 0 else (1)
# Driver Code
N = 8
#Function Call
print(swapBitGame(N))
# This code is contributed by Samim Hossain Mondal.
C#
// C# code to implement the approach
using System;
public class GFG {
// Function to find the winner
static int swapBitGame(long N)
{
int bitCount = 0;
// Calculate the number of set bit in
// N using Brian Kernighan's Algorithm
while (N != 0) {
N = (N & (N - 1));
bitCount++;
}
// If bitCount is even return 2
// else return 1
return bitCount % 2 == 0 ? 2 : 1;
}
static public void Main()
{
// Code
long N = 8;
// Function call
Console.WriteLine(swapBitGame(N));
}
}
// This code is contributed by lokesh.
JavaScript
// JavaScript code to implement the approach
// Function to find the winner
const swapBitGame = (N) => {
let bitCount = 0;
// Calculate the number of set bit in
// N using Brian Kernighan's Algorithm
while (N) {
N = (N & (N - 1));
bitCount++;
}
// If bitCount is even return 2
// else return 1
return bitCount % 2 == 0 ? 2 : 1;
}
// Driver Code
let N = 8;
// Function Call
console.log(swapBitGame(N));
// This code is contributed by rakeshsahni.
Time Complexity: O(log N)
Auxiliary Space: O(1)
Approach: Naive Recursion with memoization
Steps:
- First, check if the solution for the given input N is already present in the memoization map.
- If it is present, then return the value of the solution from the map to avoid recalculation.
- If it is not present, use a loop to iterate through all the bits of N.
- Remove the set bit by using the XOR operation.
- Then recursively call the solve function for the new value of N.
- After the recursive call, we use the OR operation to set the bit back to the original value of N.
- Check if the returned solution from the recursive call is Player 2 losing or not. If it is Player 2 losing.
- update the memoization map with the solution and return Player 1 wins.
- If we have iterated through all the bits of N and Player 2 has not lost.
- update the memoization map with Player 2 winning and return Player 2 wins.
- Finally, print the result.
Below is the code implementation of the above approach:
C++
// C++ program for the above problem using Naive Recursion with Memoization approach
#include<bits/stdc++.h>
using namespace std;
// Memoization table
unordered_map<int, int> memo;
// Recursive function
int solve(int n){
// Base case
if(n==0) return 2;
if(memo.find(n) != memo.end()) return memo[n];
int ans = 0;
for(int i=0; i<31; i++){
if(n & (1<<i)){
n ^= (1<<i);
ans = solve(n);
n |= (1<<i);
// If Player 1 wins in the current subproblem, then Player 2 will lose, so return 1.
if(ans==2) {
memo[n] = 1;
return 1;
}
}
}
// If Player 1 cannot make any move, then Player 2 wins.
memo[n] = 2;
return 2;
}
// Driver code
int main(){
int n=8;
int res = solve(n);
if(res==1) cout << "1";
else cout << "2";
return 0;
}
Java
// Java code
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class GFG {
// Memoization table
static Map<Integer, Integer> memo = new HashMap<>();
// Recursive function
static int solve(int n) {
// Base case
if (n == 0) return 2;
if (memo.containsKey(n)) return memo.get(n);
int ans = 0;
for (int i = 0; i < 31; i++) {
if ((n & (1 << i)) != 0) {
n ^= (1 << i);
ans = solve(n);
n |= (1 << i);
// If Player 1 wins in the current subproblem,
// then Player 2 will lose, so return 1.
if (ans == 2) {
memo.put(n, 1);
return 1;
}
}
}
// If Player 1 cannot make any move, then Player 2 wins.
memo.put(n, 2);
return 2;
}
// Driver code
public static void main(String[] args) {
int n = 8;
int res = solve(n);
if (res == 1) {
System.out.println("1");
} else {
System.out.println("2");
}
}
}
// This code is contributed by guptapratik
Python3
import sys
# Memoization table
memo = {}
# Recursive function
def solve(n):
# Base case
if n == 0:
return 2
if n in memo:
return memo[n]
ans = 0
for i in range(31):
if n & (1 << i):
n ^= (1 << i)
ans = solve(n)
n |= (1 << i)
# If Player 1 wins in the current subproblem,
# then Player 2 will lose, so return 1.
if ans == 2:
memo[n] = 1
return 1
# If Player 1 cannot make any move, then Player 2 wins.
memo[n] = 2
return 2
# Test case
n = 8
res = solve(n)
if res == 1:
print("1")
else:
print("2")
sys.exit(0)
C#
using System;
using System.Collections.Generic;
class Program
{
// Memoization table
static Dictionary<int, int> memo = new Dictionary<int, int>();
// Recursive function
static int Solve(int n)
{
// Base case
if (n == 0) return 2;
if (memo.ContainsKey(n)) return memo[n];
int ans = 0;
for (int i = 0; i < 31; i++)
{
if ((n & (1 << i)) != 0)
{
n ^= (1 << i);
ans = Solve(n);
// If Player 1 wins in the current subproblem, then Player 2 will lose, so return 1.
if (ans == 2)
{
memo[n] = 1;
return 1;
}
n |= (1 << i);
}
}
// If Player 1 cannot make any move, then Player 2 wins.
memo[n] = 2;
return 2;
}
// Driver code
static void Main()
{
int n = 8;
int res = Solve(n);
if (res == 1) Console.WriteLine("1");
else Console.WriteLine("2");
}
}
JavaScript
// Memoization table
const memo = new Map();
// Recursive function
function solve(n) {
// Base case
if (n === 0) return 2;
if (memo.has(n)) return memo.get(n);
let ans = 0;
for (let i = 0; i < 31; i++) {
if (n & (1 << i)) {
n ^= (1 << i);
ans = solve(n);
n |= (1 << i);
// If Player 1 wins in the current subproblem,
// then Player 2 will lose, so return 1.
if (ans === 2) {
memo.set(n, 1);
return 1;
}
}
}
// If Player 1 cannot make any move, then Player 2 wins.
memo.set(n, 2);
return 2;
}
// Driver code
const n = 8;
const res = solve(n);
if (res === 1) console.log("1");
else console.log("2");
Time Complexity: O(logN)
Auxiliary Space: O(N)
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem