Given a grid of size r x c, a coin starts at cell (1, 1). Two players, JOHN and ARYA, take turns moving the coin - JOHN moves first. On each turn, a player moves the coin from its current position (x, y) to one of these positions, as long as it stays within the grid:
- (x + 1, y), (x + 2, y), (x + 3, y) moving along the x-axis by 1 to 3 cells.
- (x, y + 1), (x, y + 2), (x, y + 3), (x, y + 4), (x, y + 5), (x, y + 6) moving along the y-axis by 1 to 6 cells.
A player who cannot make a move loses. Both players play optimally. Determine who wins.
Examples:
Input: r = 1, c = 2
Output: JOHN
Explanation: JOHN moves the coin to (1, 2), the only available move. ARYA now has no legal move (the coin is at the grid's edge in both directions), so ARYA loses.Input: r = 2, c = 2
Output: ARYA
Explanation: JOHN moves to either (1, 2) or (2, 1). Either way, ARYA moves to (2, 2). JOHN now has no legal move, so JOHN loses.
Using Game Theory (Sprague-Grundy Theorem) - O(1) Time and O(1) Space
The idea is to treat this as two independent games happening at once - one along the x-axis (moves of 1, 2, or 3 allowed) and one along the y-axis (moves of 1 through 6 allowed). Each is a classic subtraction game whose outcome repeats in a fixed cycle: the x-game repeats every 4 steps, the y-game every 7. By the Sprague-Grundy theorem, the combined game is losing for the player to move exactly when these two cycle positions match.
Step by Step Implementation (Why It Works):
- Treat the coin's movement along the x-axis and y-axis as two separate, independent games happening simultaneously.
- The x-direction allows moves of 1, 2, or 3 steps - a subtraction game whose outcome repeats with period 4.
- The y-direction allows moves of 1 through 6 steps - a subtraction game whose outcome repeats with period 7.
- Compute each game's position within its cycle: (r-1) % 4 for the x-game, (c-1) % 7 for the y-game.
- By the Sprague-Grundy theorem, the combined game is a losing position for whoever is about to move exactly when these two cycle positions are equal.
- Since JOHN moves first, ARYA wins if the cycle positions match; otherwise JOHN wins.
#include <iostream>
#include <string>
using namespace std;
string moveOnGrid(int r, int c) {
// x-direction moves are {1,2,3} -> period 4
int gx = (r - 1) % 4;
// y-direction moves are {1..6} -> period 7
int gy = (c - 1) % 7;
// ARYA wins exactly when both component cycle positions match
return (gx == gy) ? "ARYA" : "JOHN";
}
int main() {
int r = 1, c = 2;
cout << moveOnGrid(r, c) << endl;
return 0;
}
class GFG {
static String moveOnGrid(int r, int c) {
// x-direction moves are {1,2,3} -> period 4
int gx = (r - 1) % 4;
// y-direction moves are {1..6} -> period 7
int gy = (c - 1) % 7;
// ARYA wins exactly when both component cycle positions match
return (gx == gy) ? "ARYA" : "JOHN";
}
public static void main(String[] args) {
int r = 1, c = 2;
System.out.println(moveOnGrid(r, c));
}
}
def moveOnGrid(r, c):
# x-direction moves are {1,2,3} -> period 4
gx = (r - 1) % 4
# y-direction moves are {1..6} -> period 7
gy = (c - 1) % 7
# ARYA wins exactly when both component cycle positions match
return "ARYA" if gx == gy else "JOHN"
r, c = 1, 2
print(moveOnGrid(r, c))
using System;
class GFG {
static string moveOnGrid(int r, int c) {
// x-direction moves are {1,2,3} -> period 4
int gx = (r - 1) % 4;
// y-direction moves are {1..6} -> period 7
int gy = (c - 1) % 7;
// ARYA wins exactly when both component cycle positions match
return (gx == gy) ? "ARYA" : "JOHN";
}
static void Main() {
int r = 1, c = 2;
Console.WriteLine(moveOnGrid(r, c));
}
}
function moveOnGrid(r, c) {
// x-direction moves are {1,2,3} -> period 4
const gx = (r - 1) % 4;
// y-direction moves are {1..6} -> period 7
const gy = (c - 1) % 7;
// ARYA wins exactly when both component cycle positions match
return gx === gy ? "ARYA" : "JOHN";
}
// Driver Code
const r = 1, c = 2;
console.log(moveOnGrid(r, c));
Output
JOHN