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++ 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 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 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# 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 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. |
1
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++ 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 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 |
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 )
|
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" );
}
} |
// 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" );
|
1
Time Complexity: O(logN)
Auxiliary Space: O(N)