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.

Try It Yourselfredirect icon

Table of Content

**[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) == 1

Sample 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:

file

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 1

Driver 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)