Divisor Game
EasyPrompt
Alice and Bob take turns playing a game, with Alice starting first.
Initially, there is a number n on the chalkboard. On each player's turn, that player makes a move consisting of:
- Choosing any
xwith0 < x < nandn % x == 0. - Replacing the number
non the chalkboard withn - x.
Also, if a player cannot make a move, they lose the game.
Return true if and only if Alice wins the game, assuming both players play optimally.
Example 1:
Input: n = 2
Output: true
Explanation: Alice chooses 1, and Bob has no more moves.Example 2:
Input: n = 3
Output: false
Explanation: Alice chooses 1, Bob chooses 1, and Alice has no more moves.
Constraints:
1 <= n <= 1000
Approaches
2 approaches with complexity analysis and trade-offs.
This approach uses dynamic programming to solve the game. We determine the winner for each number i from 1 up to n. A player wins from a state i if they can make a move to a state j from which the other player is guaranteed to lose.
Algorithm
- Create a boolean DP array
dpof sizen + 1, initialized tofalse. - Loop
ifrom 2 ton. - Inside this loop, loop
xfrom 1 toi-1. - If
iis divisible byx, check the value ofdp[i - x]. - If
dp[i - x]isfalse, it means we found a move to a losing position for the opponent. Setdp[i] = trueand break the inner loop. - After the loops complete, return
dp[n].
Walkthrough
We can solve this game theory problem using a bottom-up dynamic programming approach. The state of the game is defined by the current number n on the chalkboard.
Let dp[i] be a boolean value indicating if the current player can win starting with the number i.
dp[i] = truemeans the current player can win.dp[i] = falsemeans the current player will lose if the opponent plays optimally.
The goal is to compute dp[n].
-
Base Case: For
n = 1, there are no valid moves (0 < x < 1is impossible). So, the player whose turn it is loses.dp[1] = false. -
Transitions: For any number
i > 1, the current player wins if they can make a move to a numberi - x(wherexis a proper divisor ofi) from which the other player loses. In other words,dp[i]istrueif there exists a divisorxofisuch thatdp[i - x]isfalse.
We can build up the dp table from i = 2 to n.
class Solution { public boolean divisorGame(int n) { boolean[] dp = new boolean[n + 1]; // In Java, boolean arrays are initialized to false. // So dp[1] is already false. for (int i = 2; i <= n; i++) { for (int x = 1; x < i; x++) { if (i % x == 0) { // Check if moving to i-x is a winning move. // A move is winning if the opponent is left in a losing state. // A losing state for the opponent is one where dp[state] is false. if (!dp[i - x]) { dp[i] = true; break; // Found a winning move, no need to check further for this i. } } } } return dp[n]; }}Complexity
Time
O(n^2). The outer loop runs `n` times, and the inner loop runs up to `n` times for each `i`. This gives a quadratic time complexity.
Space
O(n) to store the results for `n` subproblems in the DP array.
Trade-offs
Pros
It's a general and intuitive approach for solving impartial games.
Guaranteed to find the optimal solution.
Cons
Not the most efficient solution for this specific problem.
The
O(n^2)time complexity might be too slow for largern, but it's acceptable forn <= 1000.
A closer look at the game's rules and states reveals a simple pattern. The winner can be determined just by the parity of the initial number n. This approach leverages this mathematical insight for a highly efficient solution.
Algorithm
- Check if the input number
nis even. - If
nis even, returntrue. - If
nis odd, returnfalse. - This can be implemented with a single expression:
n % 2 == 0.
Walkthrough
By analyzing the game, we can deduce a simple mathematical rule that determines the winner.
Let's prove by induction that the first player (Alice) wins if n is even and loses if n is odd.
-
Base Cases:
n = 1:nis odd. Alice has no moves and loses. The rule holds.n = 2:nis even. Alice choosesx=1,nbecomes1. Bob receives1and loses. Alice wins. The rule holds.
-
Inductive Hypothesis: Assume for all integers
k < n, the current player wins ifkis even and loses ifkis odd. -
Inductive Step:
- Case 1:
nis odd. Alice must choose a divisorxofn. Sincenis odd, all of its divisorsxmust also be odd. The new number becomesn - x. The difference between two odd numbers (nandx) is always an even number. So, Alice must pass an even number to Bob. By the inductive hypothesis, Bob receives an even number and wins. Since every move Alice makes leads to a winning position for Bob, Alice will lose ifnis odd. - Case 2:
nis even. Alice can simply choosex = 1(which is always a divisor forn > 1). The new number becomesn - 1. Sincenis even,n - 1is odd. Alice can pass an odd number to Bob. By the inductive hypothesis, Bob receives an odd number and loses. Since Alice can make a move that forces Bob into a losing position, Alice will win ifnis even.
- Case 1:
Thus, the proof is complete. Alice wins if and only if n is even.
class Solution { public boolean divisorGame(int n) { return n % 2 == 0; }}Complexity
Time
O(1). The solution involves a single modulo operation, which is a constant time operation.
Space
O(1). No extra space is required.
Trade-offs
Pros
Extremely efficient in both time and space.
Very simple to implement.
Cons
Relies on a mathematical insight that might not be immediately obvious.
It's less of a general algorithmic approach and more of a problem-specific trick.
Solutions
Solution
class Solution {public boolean divisorGame(int n) { return n % 2 == 0; }}var divisorGame = function ( n ) { return n % 2 === 0 ; };class Solution {public: bool divisorGame(int n) { return n % 2 == 0; }};class Solution: def divisorGame(self, n: int) -> bool: return n % 2 == 0Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.