Find the winner between N and M based on the Integer Subtraction
Last Updated :
06 Dec, 2023
Given two integers N and M. Two players A and B are playing the game on these integers. The task is to output the winner if A starts first and last the player who makes the last moves wins. Any player is allowed to make the following move:
- Choose one integer from N or M, then subtract a multiple of the non-chosen integer from the chosen integer such that after subtraction number should be non-negative.
- The game ends when either N or M becomes 0.
Note: Both players will play optimally.
Examples:
Input: N = 14, M = 8
Output: A
Explanation: The moves of the game are as follows:
- First Move (By A):
- Chosen integer, N = 14
- Non-chosen integer, M = 8
- Subtracts 8 from N because 8 is a multiple of non-chosen (M = 8) integer. Then updated N = 6, M = 8.
- Second Move (By B):
- Chosen integer, M = 8
- Non-chosen integer, N = 6
- Subtracts 6 from M because 6 is a multiple of non-chosen (N = 6) integer. Then updated N = 6, M = 2.
- Third Move (By player A):
- Chosen integer, N = 6
- Non-chosen integer, M = 2
- Subtracts 6 from N because 6 is a multiple of non-chosen (M = 2) integer. Then updated N = 0, M = 2.
Now it can be verified that B is not able to make any move and last move made by A. Therefore, A is the winner.
Input: M = 47, N = 155
Output: A
Explanation: It can be verified that if both plays optimally, then A wins. The values of integers in series of moves will be as: (155, 47) → (61, 47) → (14, 47) → (14, 19) → (14, 9) → (4, 5) → (4, 1) → (0, 1).
Approach: Implement the idea below to solve the problem.
The problem is based on the Game Theory. It is noticeable that if directly (N%M == 0 OR M%N == 0), then surely A wins the game. Otherwise, he will try to subtract the maximum multiple from non-chose integer. Hence winner can be obtained by calculating the number of moves. If number of moves are odd then A wins else B wins.
We can create the simulation code of the game, according to the given conditions:
- Condition: (N%M ==0 || M%N ==0), Then the winner will be always A in such cases. Because the game can be win only in first move.
- Condition: (N/M>1 || M/N>1) is for the cases like (9, 2)
- In such cases like (9, 2), The optimal play will be as:
- Subtract 2 by A: (7, 2)
- Subtract 2 by B: (5, 2)
- Subtract 2 by A: (3, 2)
- Subtract 2 by B: (1, 2)
- A can’t make any move on: (0, 2)
- So, In total 4 moves were there and B wins. Same output of winner is given by code. For repeating subtraction of 2 again & again increases complexity of solution. Therefore, this special condition is mentioned. Same will be for (3, 10).
- The below two conditions handles cases, when either N or M divides other. It is different from above case as: In above case there was repeating subtraction of same value and these below 2 conditions handles the scenario where alternative or random subtraction of N or M takes place.
- If (N>M), then N%=M
- Else, then M%=N
Steps were taken to solve the problem:
- Create a variable let say Moves to store the count of moves performed and initialize it equal to 1.
- Run an infinite loop and follow below mentioned steps under the scope of loop:
- If the N is divisible by M or M is divisible by N, increment Moves and break the loop.
- If (N/M > 1) or (M/N > 1), increment Moves and break the loop.
- If (N>M), increment Moves and replace N with N%M.
- Else , increment Moves and replace M with M%N.
- If Number of Moves are odd then Output A, Else Output B.
Below is the implementation of above approach:
C++
#include <iostream>
using namespace std;
void Find_Winner( long N, long M) {
long moves = 0;
while ( true ) {
if (N % M == 0 || M % N == 0) {
moves++;
break ;
}
if (N / M > 1 || M / N > 1) {
moves++;
break ;
}
if (N >= M)
N %= M;
else
M %= N;
moves++;
}
if (moves % 2 == 1)
cout << "A" << endl;
else
cout << "B" << endl;
}
int main() {
long N = 14;
long M = 8;
Find_Winner(N, M);
return 0;
}
|
Java
import java.util.*;
class GFG {
public static void main(String[] args)
{
long N = 14 ;
long M = 8 ;
Find_Winner(N, M);
}
public static void Find_Winner( long N, long M)
{
long moves = 0 ;
while ( 1 > 0 ) {
if (N % M == 0 || M % N == 0 ) {
moves++;
break ;
}
if (N / M > 1 || M / N > 1 ) {
moves++;
break ;
}
if (N >= M)
N %= M;
else
M %= N;
moves++;
}
if (moves % 2 == 1 )
System.out.println("A");
else
System.out.println("B");
}
}
|
Python3
def find_winner(N, M):
moves = 0
while True :
if N % M = = 0 or M % N = = 0 :
moves + = 1
break
if N / M > 1 or M / N > 1 :
moves + = 1
break
if N > = M:
N % = M
else :
M % = N
moves + = 1
if moves % 2 = = 1 :
print ( "A" )
else :
print ( "B" )
if __name__ = = "__main__" :
N = 14
M = 8
find_winner(N, M)
|
C#
using System;
class GFG
{
public static void Main( string [] args)
{
long N = 14;
long M = 8;
Find_Winner(N, M);
}
public static void Find_Winner( long N, long M)
{
long moves = 0;
while ( true )
{
if (N % M == 0 || M % N == 0)
{
moves++;
break ;
}
if (N / M > 1 || M / N > 1)
{
moves++;
break ;
}
if (N >= M)
N %= M;
else
M %= N;
moves++;
}
if (moves % 2 == 1)
Console.WriteLine( "A" );
else
Console.WriteLine( "B" );
}
}
|
Javascript
function findWinner(N, M) {
let moves = 0;
while ( true ) {
if (N % M === 0 || M % N === 0) {
moves++;
break ;
}
if (N / M > 1 || M / N > 1) {
moves++;
break ;
}
if (N >= M)
N %= M;
else
M %= N;
moves++;
}
if (moves % 2 === 1)
console.log( "A" );
else
console.log( "B" );
}
const N = 14;
const M = 8;
findWinner(N, M);
|
Time Complexity: O(Moves)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...