Given three numbers n, x, and y, Geek and his friend are playing a coin game. In the beginning, there are n coins. In each move, a player can pick x, y, or 1 coin. Geek always starts the game. The player who picks the last coin wins the game. The task is to determine whether Geek will win the game or not if both players play optimally.
Examples:Â
Input: n = 5, x = 3, y = 4
Output: 1
Explanation: There are 5 coins, every player can pick 1 or 3 or 4 coins on his/her turn. Geek can win by picking 3 coins in first chance. Now 2 coins will be left so his friend will pick one coin and now Geek can win by picking the last coin.Input: n = 2, x = 3, y = 4
Output: 0
Explanation: Geek picks 1 coin and then his friend picks 1 coin.
Table of Content
[Naive Approach] Using Recursion - O(3n) Time O(n) Space
The idea is to recursively explore all possible moves (removing 1, x, or y coins) and determine that a state is winning if any move leads to a losing state for the opponent, otherwise it is losing, and since no intermediate results are stored, this approach is naive.
#include <bits/stdc++.h>
using namespace std;
// Recursive function to determine if the current player can win
bool solve(int n, int x, int y)
{
// Base Case:
// If no coins are left, current player loses
if (n == 0)
return false;
// Check if removing 1 coin leads to a losing state for opponent
if (n >= 1 &&!solve(n - 1, x, y))
return true;
// Check if removing x coins leads to a losing state for opponent
if (n >= x &&!solve(n - x, x, y))
return true;
// Check if removing y coins leads to a losing state for opponent
if (n >= y &&!solve(n - y, x, y))
return true;
// If none of the moves lead to a losing state,
// then current state is losing
return false;
}
// Function to find the winner of the game
int findWinner(int n, int x, int y)
{
// Call recursive function
// Returns 1 if first player wins, else 0
return solve(n, x, y);
}
// Driver Code
int main()
{
int n = 5, x = 3, y = 4;
cout << findWinner(n, x, y);
return 0;
}
#include <stdio.h>
// Recursive function to determine if the current player can win
int solve(int n, int x, int y)
{
// Base Case:
// If no coins are left, current player loses
if (n == 0)
return 0;
// Check if removing 1 coin leads to a losing state for opponent
if (n >= 1 &&!solve(n - 1, x, y))
return 1;
// Check if removing x coins leads to a losing state for opponent
if (n >= x &&!solve(n - x, x, y))
return 1;
// Check if removing y coins leads to a losing state for opponent
if (n >= y &&!solve(n - y, x, y))
return 1;
// If none of the moves lead to a losing state,
// then current state is losing
return 0;
}
// Function to find the winner of the game
int findWinner(int n, int x, int y)
{
// Call recursive function
// Returns 1 if first player wins, else 0
return solve(n, x, y);
}
// Driver Code
int main()
{
int n = 5, x = 3, y = 4;
printf("%d", findWinner(n, x, y));
return 0;
}
import java.util.*;
public class GFG {
// Recursive function to determine if the current player can win
static boolean solve(int n, int x, int y) {
// Base Case:
// If no coins are left, current player loses
if (n == 0)
return false;
// Check if removing 1 coin leads to a losing state for opponent
if (n >= 1 && !solve(n - 1, x, y))
return true;
// Check if removing x coins leads to a losing state for opponent
if (n >= x &&!solve(n - x, x, y))
return true;
// Check if removing y coins leads to a losing state for opponent
if (n >= y &&!solve(n - y, x, y))
return true;
// If none of the moves lead to a losing state,
// then current state is losing
return false;
}
// Function to find the winner of the game
static int findWinner(int n, int x, int y) {
// Call recursive function
// Returns 1 if first player wins, else 0
return solve(n, x, y) ? 1 : 0;
}
// Driver Code
public static void main(String[] args) {
int n = 5, x = 3, y = 4;
System.out.print(findWinner(n, x, y));
}
}
# Recursive function to determine if the current player can win
def solve(n, x, y):
# Base Case:
# If no coins are left, current player loses
if n == 0:
return False
# Check if removing 1 coin leads to a losing state for opponent
if n >= 1 and not solve(n - 1, x, y):
return True
# Check if removing x coins leads to a losing state for opponent
if n >= x and not solve(n - x, x, y):
return True
# Check if removing y coins leads to a losing state for opponent
if n >= y and not solve(n - y, x, y):
return True
# If none of the moves lead to a losing state,
# then current state is losing
return False
# Function to find the winner of the game
def findWinner(n, x, y):
# Call recursive function
# Returns 1 if first player wins, else 0
return 1 if solve(n, x, y) else 0
# Driver Code
n = 5
x = 3
y = 4
print(findWinner(n, x, y))
using System;
public class GFG
{
// Recursive function to determine if the current player can win
static bool Solve(int n, int x, int y)
{
// Base Case:
// If no coins are left, current player loses
if (n == 0)
return false;
// Check if removing 1 coin leads to a losing state for opponent
if (n >= 1 && !Solve(n - 1, x, y))
return true;
// Check if removing x coins leads to a losing state for opponent
if (n >= x &&!Solve(n - x, x, y))
return true;
// Check if removing y coins leads to a losing state for opponent
if (n >= y &&!Solve(n - y, x, y))
return true;
// If none of the moves lead to a losing state,
// then current state is losing
return false;
}
// Function to find the winner of the game
static int FindWinner(int n, int x, int y)
{
// Call recursive function
// Returns 1 if first player wins, else 0
return Solve(n, x, y)? 1 : 0;
}
// Driver Code
public static void Main()
{
int n = 5, x = 3, y = 4;
Console.Write(FindWinner(n, x, y));
}
}
// Recursive function to determine if the current player can win
function solve(n, x, y) {
// Base Case:
// If no coins are left, current player loses
if (n === 0)
return false;
// Check if removing 1 coin leads to a losing state for opponent
if (n >= 1 && !solve(n - 1, x, y))
return true;
// Check if removing x coins leads to a losing state for opponent
if (n >= x &&!solve(n - x, x, y))
return true;
// Check if removing y coins leads to a losing state for opponent
if (n >= y &&!solve(n - y, x, y))
return true;
// If none of the moves lead to a losing state,
// then current state is losing
return false;
}
// Function to find the winner of the game
function findWinner(n, x, y) {
// Call recursive function
// Returns 1 if first player wins, else 0
return solve(n, x, y)? 1 : 0;
}
// Driver Code
let n = 5, x = 3, y = 4;
console.log(findWinner(n, x, y));
Output
1
[Expected Approach] Using Dynamic Programming - O(n) Time O(n) Space
The idea is to use Dynamic Programming to build a dp array from 0 to n, where each state is marked winning if any move (removing 1, x, or y coins) leads to a losing state for the opponent, otherwise it is losing.
Working of Approach:
- Initialize DP array with base cases: dp[0] = 0 (losing state) and dp[1] = 1 (winning state).
- Traverse from i = 2 to n and evaluate each state.
- For each i, check if removing 1 coin leads to a losing state (dp[i - 1] == 0), then mark dp[i] = 1.
- Otherwise, check if removing x coins leads to a losing state (i >= x && dp[i - x] == 0), then mark dp[i] = 1.
- Otherwise, check if removing y coins leads to a losing state (i >= y && dp[i - y] == 0), then mark dp[i] = 1.
- If none of the moves lead to a losing state, mark dp[i] = 0.
- Finally, return dp[n], where 1 indicates the first player wins and 0 indicates the first player lose
#include <bits/stdc++.h>
using namespace std;
// Function to determine the winner of the game
int findWinner(int n, int x, int y)
{
// Create a DP array where:
// dp[i] = 1 -> current player can win with i coins
// dp[i] = 0 -> current player loses with i coins
int dp[n + 1];
// Base cases:
// If no coins are left, player loses
dp[0] = 0;
// If 1 coin is present, player can remove it and win
dp[1] = 1;
// Fill the DP array from 2 to n
for (int i = 2; i <= n; i++)
{
// Check if removing 1 coin leads to a losing state
if (i - 1 >= 0 && dp[i - 1] == 0)
dp[i] = 1;
// Check if removing x coins leads to a losing state
else if (i - x >= 0 && dp[i - x] == 0)
dp[i] = 1;
// Check if removing y coins leads to a losing state
else if (i - y >= 0 && dp[i - y] == 0)
dp[i] = 1;
// If all moves lead to winning states, current state is losing
else
dp[i] = 0;
}
return dp[n];
}
// Driver Code
int main()
{
int n = 5, x = 3, y = 4;
cout << findWinner(n, x, y);
return 0;
}
#include <stdio.h>
// Function to determine the winner of the game
int findWinner(int n, int x, int y)
{
// Create a DP array where:
// dp[i] = 1 -> current player can win with i coins
// dp[i] = 0 -> current player loses with i coins
int dp[n + 1];
// Base cases:
// If no coins are left, player loses
dp[0] = 0;
// If 1 coin is present, player can remove it and win
dp[1] = 1;
// Fill the DP array from 2 to n
for (int i = 2; i <= n; i++)
{
// Check if removing 1 coin leads to a losing state
if (i - 1 >= 0 && dp[i - 1] == 0)
dp[i] = 1;
// Check if removing x coins leads to a losing state
else if (i - x >= 0 && dp[i - x] == 0)
dp[i] = 1;
// Check if removing y coins leads to a losing state
else if (i - y >= 0 && dp[i - y] == 0)
dp[i] = 1;
// If all moves lead to winning states, current state is losing
else
dp[i] = 0;
}
return dp[n];
}
// Driver Code
int main()
{
int n = 5, x = 3, y = 4;
printf("%d", findWinner(n, x, y));
return 0;
}
// Function to determine the winner of the game
public class GFG {
public static int findWinner(int n, int x, int y) {
// Create a DP array where:
// dp[i] = 1 -> current player can win with i coins
// dp[i] = 0 -> current player loses with i coins
int[] dp = new int[n + 1];
// Base cases:
// If no coins are left, player loses
dp[0] = 0;
// If 1 coin is present, player can remove it and win
dp[1] = 1;
// Fill the DP array from 2 to n
for (int i = 2; i <= n; i++) {
// Check if removing 1 coin leads to a losing state
if (i - 1 >= 0 && dp[i - 1] == 0)
dp[i] = 1;
// Check if removing x coins leads to a losing state
else if (i - x >= 0 && dp[i - x] == 0)
dp[i] = 1;
// Check if removing y coins leads to a losing state
else if (i - y >= 0 && dp[i - y] == 0)
dp[i] = 1;
// If all moves lead to winning states, current state is losing
else
dp[i] = 0;
}
return dp[n];
}
public static void main(String[] args) {
int n = 5, x = 3, y = 4;
System.out.println(findWinner(n, x, y));
}
}
# Function to determine the winner of the game
def findWinner(n, x, y):
# Create a DP array where:
# dp[i] = 1 -> current player can win with i coins
# dp[i] = 0 -> current player loses with i coins
dp = [0] * (n + 1)
# Base cases:
# If no coins are left, player loses
dp[0] = 0
# If 1 coin is present, player can remove it and win
dp[1] = 1
# Fill the DP array from 2 to n
for i in range(2, n + 1):
# Check if removing 1 coin leads to a losing state
if i - 1 >= 0 and dp[i - 1] == 0:
dp[i] = 1
# Check if removing x coins leads to a losing state
elif i - x >= 0 and dp[i - x] == 0:
dp[i] = 1
# Check if removing y coins leads to a losing state
elif i - y >= 0 and dp[i - y] == 0:
dp[i] = 1
# If all moves lead to winning states, current state is losing
else:
dp[i] = 0
return dp[n]
# Driver Code
n = 5
x = 3
y = 4
print(findWinner(n, x, y))
// Function to determine the winner of the game
using System;
public class GFG
{
public static int findWinner(int n, int x, int y)
{
// Create a DP array where:
// dp[i] = 1 -> current player can win with i coins
// dp[i] = 0 -> current player loses with i coins
int[] dp = new int[n + 1];
// Base cases:
// If no coins are left, player loses
dp[0] = 0;
// If 1 coin is present, player can remove it and win
dp[1] = 1;
// Fill the DP array from 2 to n
for (int i = 2; i <= n; i++)
{
// Check if removing 1 coin leads to a losing state
if (i - 1 >= 0 && dp[i - 1] == 0)
dp[i] = 1;
// Check if removing x coins leads to a losing state
else if (i - x >= 0 && dp[i - x] == 0)
dp[i] = 1;
// Check if removing y coins leads to a losing state
else if (i - y >= 0 && dp[i - y] == 0)
dp[i] = 1;
// If all moves lead to winning states, current state is losing
else
dp[i] = 0;
}
return dp[n];
}
public static void Main()
{
int n = 5, x = 3, y = 4;
Console.WriteLine(findWinner(n, x, y));
}
}
// Function to determine the winner of the game
function findWinner(n, x, y) {
// Create a DP array where:
// dp[i] = 1 -> current player can win with i coins
// dp[i] = 0 -> current player loses with i coins
let dp = Array(n + 1).fill(0);
// Base cases:
// If no coins are left, player loses
dp[0] = 0;
// If 1 coin is present, player can remove it and win
dp[1] = 1;
// Fill the DP array from 2 to n
for (let i = 2; i <= n; i++) {
// Check if removing 1 coin leads to a losing state
if (i - 1 >= 0 && dp[i - 1] === 0)
dp[i] = 1;
// Check if removing x coins leads to a losing state
else if (i - x >= 0 && dp[i - x] === 0)
dp[i] = 1;
// Check if removing y coins leads to a losing state
else if (i - y >= 0 && dp[i - y] === 0)
dp[i] = 1;
// If all moves lead to winning states, current state is losing
else
dp[i] = 0;
}
return dp[n];
}
// Driver Code
let n = 5, x = 3, y = 4;
console.log(findWinner(n, x, y));
Output
1