Game of Chocolates | Wythoff's Game

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 Yourself
redirect icon

[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<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))
            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<int>> dp(A + 1, vector<int>(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");
}

Output
Dolly

[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...
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");

Output
Bunty

Time Complexity: O(1)
Auxiliary Space: O(1)

Comment