Game of Chocolates | Wythoff's Game (original) (raw)
Last Updated : 23 Jul, 2025
Bunty and Dolly are playing a game, described as follows:
There are two boxes having **A and **B number of chocolates respectively. Both can eat L (L >= 1) chocolates from any one box or L chocolates from both boxes in one move. They play the game alternatively and the last one to eat the chocolate will be the winner.
You have to help Bunty in deciding who should play first such that Dolly is always the winner. Assume that both players play optimally.
**Note: This game is also known as Wythoff's Game.
**Examples:
**Input: A = 1 and B = 2
**Output: Bunty
**Explanation: If Bunty starts first, all the possible states after Bunty eats chocolates are (0, 2), (1, 1), (1, 0). These are all wining states for Dolly**Input: A = 1 and B = 3
**Output: Dolly
**Explanation: If Dolly starts first, all the possible states after Dolly eats chocolates are (0, 3), (1, 2), (1, 1), (1, 0), (0, 2). Out of these, (1, 2) is the winning state for Dolly.
Table of Content
- [Naive Approach] Using Recursion and Memoization - O(A * B) Time and O(A * B) Space
- [Expected Approach] Using Golden Ratio - O(1) Time and O(1) Space
**[Naive Approach] Using Recursion and Memoization - O(A * B) Time and O(A * B) Space
All states of chocolates can be uniquely identified using two integers ****(n, m)** where n and m are number of chocolates in the first and second box respectively. Now each state can be classified into two categories:
**Cold State - State from which the current player will always lose the game. This is a state where all the possible moves will result in losing of the current player. Example: (1, 2), (2, 4)
**Hot State - State from which the current player can win the game. This is a state where at least one of the moves will result in winning of the current player.
The task is to check if the given state (A, B) is a hot state or cold state and if it is a hot state, Dolly should start otherwise Bunty should start the game. In the recursive function, try for all the possible combinations by eating chocolates from the first box or the second box or from both the boxes simultaneously.
We can use Dynamic Programming and memoize the solution using a dp[][] table such that dp[i][j] stores the result for state (i, j).
Below is the implementation of the algorithm:
C++ `
// C++ Code for Wythoff's Game
#include <bits/stdc++.h> using namespace std;
int isHotState(int A, int B, vector<vector> &dp) { // If there are no chocolates, then the current player // loses if (A == 0 && B == 0) return 0;
// If one box is empty and other box is not empty, the
// current player wins by eating all the remaining
// chocolates from the box
if (A == 0 || B == 0)
return 1;
// Check if the result has been already calculated previously
if(dp[A][B] != -1)
return dp[A][B];
// Try all combinations by eating chocolates from the
// first box
for (int eaten = 1; eaten <= A; eaten++) {
if (!isHotState(A - eaten, B, dp))
return dp[A][B] = 1;
}
// Try all combinations by eating chocolates from the
// second box
for (int eaten = 1; eaten <= B; eaten++) {
if (!isHotState(A, B - eaten, dp))
return dp[A][B] = 1;
}
// Try all the combinations by eating chocolates from
// both the boxes simultaneously
for (int eaten = 1; eaten <= min(A, B); eaten++) {
if (!isHotState(A - eaten, B - eaten, dp))
return dp[A][B] = 1;
}
return dp[A][B] = 0;}
bool game(int A, int B) { vector<vector> dp(A + 1, vector(B + 1, -1));
return isHotState(A, B, dp) == 1;}
int main() { // Sample Input int A = 1, B = 3;
// Function call
if (game(A, B))
cout << "Dolly";
else
cout << "Bunty";
return 0;}
Java
// Java Program for Wythoff’s Game
import java.util.Arrays; public class GFG {
// Function to determine if the current state is a "hot
// state" (winning position for the current player)
public static int isHotState(int A, int B, int[][] dp)
{
// If there are no chocolates, then the current
// player loses
if (A == 0 && B == 0) {
return 0;
}
// If one box is empty and other box is not empty,
// the current player wins by eating all the
// remaining chocolates from the box
if (A == 0 || B == 0) {
return 1;
}
// Check if the result has been already calculated
// previously
if (dp[A][B] != -1) {
return dp[A][B];
}
// Try all combinations by eating chocolates from
// the first box
for (int eaten = 1; eaten <= A; eaten++) {
if (isHotState(A - eaten, B, dp) == 0) {
return dp[A][B] = 1;
}
}
// Try all combinations by eating chocolates from
// the second box
for (int eaten = 1; eaten <= B; eaten++) {
if (isHotState(A, B - eaten, dp) == 0) {
return dp[A][B] = 1;
}
}
// Try all the combinations by eating chocolates
// from both the boxes simultaneously
for (int eaten = 1; eaten <= Math.min(A, B);
eaten++) {
if (isHotState(A - eaten, B - eaten, dp) == 0) {
return dp[A][B] = 1;
}
}
return dp[A][B] = 0;
}
// Main game function that initializes the DP table and
// determines the winner
public static boolean game(int A, int B)
{
int[][] dp = new int[A + 1][B + 1];
for (int[] row : dp) {
Arrays.fill(row, -1);
}
return isHotState(A, B, dp) == 1;
}
public static void main(String[] args)
{
// Sample Input
int A = 1, B = 3;
// Function call
if (game(A, B)) {
System.out.println("Dolly");
}
else {
System.out.println("Bunty");
}
}}
Python
Python Code for Wythoff's Game
def is_hot_state(A, B, dp): # If there are no chocolates, then the current player loses if A == 0 and B == 0: return 0
# If one box is empty and the other box is not empty, the
# current player wins by eating all the remaining chocolates from the box
if A == 0 or B == 0:
return 1
# Check if the result has been already calculated previously
if dp[A][B] != -1:
return dp[A][B]
# Try all combinations by eating chocolates from the first box
for eaten in range(1, A + 1):
if is_hot_state(A - eaten, B, dp) == 0:
dp[A][B] = 1
return dp[A][B]
# Try all combinations by eating chocolates from the second box
for eaten in range(1, B + 1):
if is_hot_state(A, B - eaten, dp) == 0:
dp[A][B] = 1
return dp[A][B]
# Try all the combinations by eating chocolates from both the boxes simultaneously
for eaten in range(1, min(A, B) + 1):
if is_hot_state(A - eaten, B - eaten, dp) == 0:
dp[A][B] = 1
return dp[A][B]
dp[A][B] = 0
return dp[A][B]def game(A, B): # Initialize the DP table dp = [[-1 for _ in range(B + 1)] for _ in range(A + 1)]
# Check the initial state
return is_hot_state(A, B, dp) == 1Sample Input
A = 1 B = 3
Function call
if game(A, B): print("Dolly") else: print("Bunty")
C#
using System;
class GFG { // Function to determine if the current state is a "hot state" (winning position for the current player) static int IsHotState(int A, int B, int[,] dp) { // If there are no chocolates, then the current player loses if (A == 0 && B == 0) return 0;
// If one box is empty and the other box is not empty, the current player wins by eating all the remaining chocolates from the box
if (A == 0 || B == 0)
return 1;
// Check if the result has been already calculated previously
if (dp[A, B] != -1)
return dp[A, B];
// Try all combinations by eating chocolates from the first box
for (int eaten = 1; eaten <= A; eaten++)
{
if (IsHotState(A - eaten, B, dp) == 0)
{
dp[A, B] = 1;
return dp[A, B];
}
}
// Try all combinations by eating chocolates from the second box
for (int eaten = 1; eaten <= B; eaten++)
{
if (IsHotState(A, B - eaten, dp) == 0)
{
dp[A, B] = 1;
return dp[A, B];
}
}
// Try all the combinations by eating chocolates from both the boxes simultaneously
for (int eaten = 1; eaten <= Math.Min(A, B); eaten++)
{
if (IsHotState(A - eaten, B - eaten, dp) == 0)
{
dp[A, B] = 1;
return dp[A, B];
}
}
dp[A, B] = 0;
return dp[A, B];
}
// Main game function that initializes the DP table and determines the winner
static bool Game(int A, int B)
{
// Initialize the DP table with -1 for uncomputed states
int[,] dp = new int[A + 1, B + 1];
for (int i = 0; i <= A; i++)
{
for (int j = 0; j <= B; j++)
{
dp[i, j] = -1;
}
}
// Check the initial state
return IsHotState(A, B, dp) == 1;
}
static void Main()
{
// Sample Input
int A = 1, B = 3;
// Function call
if (Game(A, B))
Console.WriteLine("Dolly");
else
Console.WriteLine("Bunty");
}}
JavaScript
// JavaScript Code for Wythoff's Game
function isHotState(A, B, dp) { // If there are no chocolates, then the current player loses if (A === 0 && B === 0) return 0;
// If one box is empty and the other box is not empty, the current player wins by eating all the remaining chocolates from the box
if (A === 0 || B === 0) return 1;
// Check if the result has been already calculated previously
if (dp[A][B] !== -1) return dp[A][B];
// Try all combinations by eating chocolates from the first box
for (let eaten = 1; eaten <= A; eaten++) {
if (isHotState(A - eaten, B, dp) === 0) {
dp[A][B] = 1;
return dp[A][B];
}
}
// Try all combinations by eating chocolates from the second box
for (let eaten = 1; eaten <= B; eaten++) {
if (isHotState(A, B - eaten, dp) === 0) {
dp[A][B] = 1;
return dp[A][B];
}
}
// Try all the combinations by eating chocolates from both the boxes simultaneously
for (let eaten = 1; eaten <= Math.min(A, B); eaten++) {
if (isHotState(A - eaten, B - eaten, dp) === 0) {
dp[A][B] = 1;
return dp[A][B];
}
}
dp[A][B] = 0;
return dp[A][B];}
function game(A, B) { // Initialize the DP table with -1 for uncomputed states const dp = Array.from({ length: A + 1 }, () => Array(B + 1).fill(-1));
// Check the initial state
return isHotState(A, B, dp) === 1;}
// Sample Input const A = 1, B = 3;
// Function call if (game(A, B)) { console.log("Dolly"); } else { console.log("Bunty"); }
`
[Expected Approach] Using Golden Ratio - O(1) Time and O(1) Space
On observing carefully, if we plot all cold states in a graph then the ratio of the lines come out to be **Φ and **1/Φ, where **Φ is the golden ratio (which is (1 + sqrt(5))/2). It is also observed that all the coordinates of cold positions are unique and their x and y coordinates differ by k where k >= 1. So, the cold positions can be calculated by floor value of ****(k*Φ, k*Φ*Φ)** where **k>=1. For example:
- If **k = 1, cold state = (floor(1 * Φ), floor(1 * Φ * Φ)) = (floor(1.618), floor(2.618)) = ****(1, 2)** and difference between coordinates = k = 1.
- If **k = 2, cold state = (floor(2 * Φ), floor(2 * Φ * Φ)) = (floor(3.236), floor(5.236)) = ****(3, 5)** and difference between coordinates = k = 2.
- If **k = 3, cold state = (floor(3 * Φ), floor(3 * Φ * Φ)) = (floor(4.854), floor(7.854)) = ****(4, 7)** and the difference between coordinates = k = 3. And so on...
So, we can check whether (A, B) is a cold state by finding value of k = abs(A - B) and then finding the floor value of ****(k*Φ, k*Φ*Φ)**. If A = k*Φ and B = k*Φ*Φ, then (A, B) is a cold state, so Bunty should start the game. Otherwise, (A, B) is a hot state and Dolly should start the game.
Below is the implementation of the above approach:
C++ `
// C++ code to solve Wythoff’s Game
#include <bits/stdc++.h> using namespace std;
// Function to decide who should play first bool game(int A, int B) { // Swap the value if A > B if (A > B) swap(A, B);
int k = B - A;
long double goldenRatio = (1 + sqrt(5)) / 2;
int C = (int)(goldenRatio * k);
// Return answer
return (A == C) ? 0 : 1;}
// Driver Code int main() { int A = 1, B = 3;
// Function call
cout << (game(A, B) ? "Dolly" : "Bunty") << endl;
return 0;}
Java
// Java code to solve Wythoff’s Game
public class WythoffGame {
// Function to decide who should play first
public static boolean game(int A, int B) {
// Swap the value if A > B
if (A > B) {
int temp = A;
A = B;
B = temp;
}
int k = B - A;
double goldenRatio = (1 + Math.sqrt(5)) / 2;
int C = (int) (goldenRatio * k);
// Return answer
return (A == C) ? false : true;
}
public static void main(String[] args) {
// Sample Input
int A = 1, B = 3;
// Function call
System.out.println(game(A, B) ? "Dolly" : "Bunty");
}}
Python
Python Program to find solve Wythoff's Game
import math
Function to decide who should play first
def game(A, B): # Swap the value if A > B if A > B: A, B = B, A
k = B - A
golden_ratio = (1 + math.sqrt(5)) / 2
C = int(golden_ratio * k)
return 0 if A == C else 1Driver Code
A = 1 B = 3
Function call
print("Dolly" if game(A, B) == 1 else "Bunty")
C#
// C# code to solve Wythoff’s Game
using System; class GFG { // Function to decide who should play first static int Game(int A, int B) { // Swap the values if A > B if (A > B) { int temp = A; A = B; B = temp; }
int k = B - A;
double goldenRatio = (1 + Math.Sqrt(5)) / 2;
int C = (int)(goldenRatio * k);
// Return answer
return (A == C) ? 0 : 1;
}
// Driver Code
static void Main()
{
int A = 1;
int B = 3;
// Function call
Console.WriteLine(Game(A, B) == 1 ? "Dolly" : "Bunty");
}}
JavaScript
// JavaScript code to solve Wythoff’s Game
// Function to decide who should play first function game(A, B) {
if (A > B) {
[A, B] = [B, A];
}
const k = B - A;
const goldenRatio = (1 + Math.sqrt(5)) / 2;
const C = Math.floor(goldenRatio * k);
// Return answer
return (A === C) ? 0 : 1; }
// Driver Code
const A = 1;
const B = 3;
// Function call and output console.log(game(A, B) ? "Dolly" : "Bunty");
`
**Time Complexity: O(1)
**Auxiliary Space: O(1)
