Facebook Pixel

3222. Find the Winning Player in Coin Game

EasyMathGame TheorySimulation
Leetcode Link

Problem Description

You have two types of coins:

  • x coins with value 75 each
  • y coins with value 10 each

Alice and Bob play a turn-based game starting with Alice. In each turn, a player must pick up coins with a total value of exactly 115. The player who cannot make a valid move (cannot collect coins totaling 115) loses the game.

Both players play optimally, meaning they make the best possible moves to try to win.

Your task is to determine who wins the game and return the winner's name as a string ("Alice" or "Bob").

For example, to make a total of 115, a player could take:

  • 1 coin of value 75 and 4 coins of value 10 (75 + 40 = 115)
  • Any other valid combination that sums to exactly 115

The key insight is that since 115 = 75 + 40, and the only way to make 115 with these coin values is to use 1 coin of value 75 and 4 coins of value 10. However, you could also use different combinations like 0 coins of value 75 and 11.5 coins of value 10 (but since we need whole coins, this isn't valid), or explore if there are other valid combinations. Actually, checking the possibilities:

  • Using 0 coins of 75: would need 115/10 = 11.5 coins of value 10 (not possible with whole coins)
  • Using 1 coin of 75: would need (115-75)/10 = 4 coins of value 10 (valid)
  • Using 2 or more coins of 75: would exceed 115 (since 2×75 = 150 > 115)

Therefore, each turn consumes exactly 1 coin of value 75 and 4 coins of value 10.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Since each turn requires exactly 115 in total value, let's first figure out what combinations are possible with coins of value 75 and 10.

To make 115:

  • If we use 0 coins of 75: we need 115/10 = 11.5 coins of 10 (impossible - not a whole number)
  • If we use 1 coin of 75: we need (115-75)/10 = 4 coins of 10 (valid!)
  • If we use 2 coins of 75: we get 2×75 = 150, which already exceeds 115 (impossible)

So the only valid combination is 1 coin of value 75 and 4 coins of value 10.

Now, since Alice goes first and players alternate, the winner depends on the total number of valid moves possible. If the total number of moves is odd, Alice wins (she makes the last valid move). If it's even, Bob wins.

How many rounds can be played? We're limited by whichever resource runs out first:

  • We can use the 75-value coins for at most x rounds
  • We can use the 10-value coins for at most y/4 rounds (since we need 4 per round)

Therefore, the maximum number of rounds is k = min(x, y/4).

After k complete rounds:

  • Remaining 75-value coins: x - k
  • Remaining 10-value coins: y - 4k

If k is even, it's Alice's turn again. She wins if she can make one more move (needs at least 1 coin of 75 and 4 coins of 10). Otherwise, Bob wins.

If k is odd, Bob just made the last complete move, so Alice wins.

The solution cleverly optimizes this by pairing up moves. Since each pair of moves uses 2 coins of 75 and 8 coins of 10, we can calculate pairs as k = min(x/2, y/8). After k pairs, if Alice can still make a move with the remaining coins, she wins; otherwise, Bob wins.

Learn more about Math patterns.

Solution Approach

The solution uses a mathematical approach to determine the winner efficiently without simulating the entire game.

Since each turn requires exactly 1 coin of value 75 and 4 coins of value 10, we can think about the game in terms of pairs of moves:

  • Each pair of moves (2 turns) consumes 2 coins of value 75 and 8 coins of value 10
  • After an even number of moves, it's Alice's turn again
  • After an odd number of moves, it's Bob's turn

The implementation calculates how many complete pairs of moves can be made:

k = min(x // 2, y // 8)

This gives us the maximum number of move pairs possible, limited by whichever resource runs out first:

  • x // 2: maximum pairs based on 75-value coins
  • y // 8: maximum pairs based on 10-value coins

After k pairs of moves, we update the remaining coins:

x -= k * 2
y -= k * 8

Now, after k pairs (which means 2k total moves), it's Alice's turn again. The key decision point:

  • If Alice can make another valid move (needs x >= 1 and y >= 4), she makes the (2k + 1)-th move and Bob cannot continue, so Alice wins
  • If Alice cannot make a valid move, Bob wins since Alice is stuck

The condition x and y >= 4 checks if Alice has at least 1 coin of value 75 (x is truthy, meaning x > 0) and at least 4 coins of value 10 (y >= 4).

The return statement elegantly captures this logic:

return "Alice" if x and y >= 4 else "Bob"

This approach avoids simulating each individual turn and directly computes the game outcome in O(1) time with O(1) space.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through an example with x = 5 coins of value 75 and y = 20 coins of value 10.

Step 1: Calculate maximum pairs of moves

  • Each pair of moves uses 2 coins of value 75 and 8 coins of value 10
  • Maximum pairs based on 75-value coins: 5 // 2 = 2 pairs
  • Maximum pairs based on 10-value coins: 20 // 8 = 2 pairs
  • So k = min(2, 2) = 2 pairs can be played

Step 2: Simulate the pairs

  • Pair 1 (Moves 1-2):
    • Alice's move: Takes 1×75 + 4×10 = 115. Remaining: 4×75, 16×10
    • Bob's move: Takes 1×75 + 4×10 = 115. Remaining: 3×75, 12×10
  • Pair 2 (Moves 3-4):
    • Alice's move: Takes 1×75 + 4×10 = 115. Remaining: 2×75, 8×10
    • Bob's move: Takes 1×75 + 4×10 = 115. Remaining: 1×75, 4×10

Step 3: Check if Alice can make another move After 2 pairs (4 total moves), it's Alice's turn again with:

  • Remaining 75-value coins: x = 5 - (2 × 2) = 1
  • Remaining 10-value coins: y = 20 - (2 × 8) = 4

Alice needs at least 1 coin of value 75 and 4 coins of value 10 to make a valid move.

  • She has exactly 1×75 and 4×10, so she CAN make move #5
  • After Alice's 5th move: 0×75, 0×10 remaining
  • Bob cannot make a valid move (no coins left)

Result: Alice wins!

This matches our formula: After k=2 pairs, we have x=1 and y=4, so the condition x and y >= 4 is true (1 is truthy and 4 >= 4), returning "Alice".

Solution Implementation

1class Solution:
2    def losingPlayer(self, x: int, y: int) -> str:
3        # Calculate the maximum number of complete rounds both players can play
4        # Each round requires 2 units of x and 8 units of y
5        complete_rounds = min(x // 2, y // 8)
6      
7        # Calculate remaining resources after complete rounds
8        remaining_x = x - complete_rounds * 2
9        remaining_y = y - complete_rounds * 8
10      
11        # Check if Alice can make one more move with remaining resources
12        # Alice needs at least 1 unit of x and 4 units of y for a valid move
13        if remaining_x >= 1 and remaining_y >= 4:
14            return "Alice"
15        else:
16            return "Bob"
17
1class Solution {
2    public String losingPlayer(int x, int y) {
3        // Calculate the maximum number of complete rounds both players can play together
4        // Each round requires 2 units of x and 8 units of y
5        int completeRounds = Math.min(x / 2, y / 8);
6      
7        // Remove the resources used in complete rounds
8        x -= completeRounds * 2;
9        y -= completeRounds * 8;
10      
11        // After complete rounds, check if Alice (who plays next) can make one more move
12        // Alice needs at least 1 unit of x and 4 units of y to play
13        // If Alice can play, she wins (Bob loses); otherwise, Bob wins (Alice loses)
14        return (x > 0 && y >= 4) ? "Alice" : "Bob";
15    }
16}
17
1class Solution {
2public:
3    string losingPlayer(int x, int y) {
4        // Calculate the maximum number of complete rounds both players can play together
5        // Each round requires 2 units of x and 8 units of y
6        int completeRounds = min(x / 2, y / 8);
7      
8        // Update remaining resources after k complete rounds
9        x -= completeRounds * 2;
10        y -= completeRounds * 8;
11      
12        // Determine the winner based on remaining resources
13        // If there's at least 1 x and 4 y remaining, Alice can make one more move and wins
14        // Otherwise, Bob wins (either Alice can't move or the rounds were even)
15        return (x >= 1 && y >= 4) ? "Alice" : "Bob";
16    }
17};
18
1/**
2 * Determines the losing player in a game where players take turns
3 * removing coins (2 of value x and 8 of value y per turn)
4 * @param x - Number of coins with value 2
5 * @param y - Number of coins with value 8
6 * @returns The name of the losing player ('Alice' or 'Bob')
7 */
8function losingPlayer(x: number, y: number): string {
9    // Calculate the maximum number of complete turns possible
10    // Each turn requires 2 x-coins and 8 y-coins
11    const maxCompleteTurns: number = Math.min(Math.floor(x / 2), Math.floor(y / 8));
12  
13    // Update remaining coins after all complete turns
14    x -= maxCompleteTurns * 2;
15    y -= maxCompleteTurns * 8;
16  
17    // Check if one more turn is possible (requires 1 x-coin and 4 y-coins)
18    // If possible, Alice gets an extra turn and Bob loses
19    // Otherwise, Alice cannot make another move and loses
20    return (x >= 1 && y >= 4) ? 'Alice' : 'Bob';
21}
22

Time and Space Complexity

The time complexity is O(1) because the code performs a fixed number of arithmetic operations regardless of the input size. The operations include:

  • Computing min(x // 2, y // 8) - constant time
  • Two subtraction operations x -= k * 2 and y -= k * 8 - constant time
  • A conditional check x and y >= 4 - constant time
  • Returning a string - constant time

The space complexity is O(1) because the algorithm only uses a constant amount of extra space. The only additional variable created is k, which stores a single integer value. No data structures that grow with input size are used.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Misunderstanding the Turn Calculation Logic

Pitfall: A common mistake is thinking that after k pairs of moves (2k total moves), it's Bob's turn instead of Alice's turn. This leads to reversing the winner logic.

Why it happens: The confusion arises from not carefully tracking whose turn it is after an even number of moves. Remember:

  • After 0 moves: Alice's turn
  • After 1 move: Bob's turn
  • After 2 moves: Alice's turn
  • After 3 moves: Bob's turn
  • After 2k moves: Alice's turn

Solution: Always remember that Alice starts first, so after any even number of moves, it's Alice's turn again.

2. Incorrect Move Validation

Pitfall: Using x >= 1 and y >= 4 instead of x and y >= 4 (or equivalently x > 0 and y >= 4).

Why it's problematic: While both work in this case, the original code uses Python's truthy/falsy behavior where x evaluates to False when x == 0. Some developers might "correct" this to x >= 1 thinking it's clearer, but then accidentally write something like x >= 1 or y >= 4 (using OR instead of AND), which would be incorrect.

Solution: Be consistent and clear with your boolean logic. Either use:

if remaining_x >= 1 and remaining_y >= 4:

or

if remaining_x > 0 and remaining_y >= 4:

3. Overcomplicated Game Simulation

Pitfall: Attempting to simulate the entire game turn by turn:

def losingPlayer(self, x: int, y: int) -> str:
    turn = 0
    while x >= 1 and y >= 4:
        x -= 1
        y -= 4
        turn += 1
    return "Bob" if turn % 2 == 1 else "Alice"

Why it's problematic: While this works, it's inefficient with O(min(x, y/4)) time complexity when the mathematical approach achieves O(1).

Solution: Recognize the pattern that every 2 moves consume fixed resources (2 coins of 75, 8 coins of 10), allowing you to calculate the outcome directly without simulation.

4. Integer Division Confusion

Pitfall: Not understanding why we use min(x // 2, y // 8) for complete pairs instead of checking individual moves.

Why it matters: Each pair of moves requires exactly 2 coins of value 75 and 8 coins of value 10. We must ensure both resources are sufficient for complete pairs. Using min(x, y // 4) would count individual moves but wouldn't properly account for pairs.

Solution: Always think in terms of complete pairs (2 moves) first, then check if one additional move is possible. This simplifies the logic and ensures correct turn attribution.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which data structure is used to implement recursion?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More