Divisor Game

easy dynamic programming game theory math

Problem

Alice and Bob take turns, with Alice going first. They share a number n on a chalkboard. On a turn the current player picks a divisor x with 0 < x < n and n % x == 0, then replaces n with n − x. A player who cannot move (when n == 1) loses. Assuming both play optimally, return true if Alice wins.

Inputn = 4
Outputtrue
Alice picks x = 2 (or x = 1), eventually leaving Bob stuck at n = 1. Every even n is a win for Alice.

def divisor_game(n):
    win = [False] * (n + 1)
    for cur in range(2, n + 1):
        for x in range(1, cur):
            if cur % x == 0 and not win[cur - x]:
                win[cur] = True
                break
    return win[n]
function divisorGame(n) {
  const win = new Array(n + 1).fill(false);
  for (let cur = 2; cur <= n; cur++) {
    for (let x = 1; x < cur; x++) {
      if (cur % x === 0 && !win[cur - x]) {
        win[cur] = true;
        break;
      }
    }
  }
  return win[n];
}
class Solution {
    public boolean divisorGame(int n) {
        boolean[] win = new boolean[n + 1];
        for (int cur = 2; cur <= n; cur++) {
            for (int x = 1; x < cur; x++) {
                if (cur % x == 0 && !win[cur - x]) {
                    win[cur] = true;
                    break;
                }
            }
        }
        return win[n];
    }
}
bool divisorGame(int n) {
    vector<bool> win(n + 1, false);
    for (int cur = 2; cur <= n; cur++) {
        for (int x = 1; x < cur; x++) {
            if (cur % x == 0 && !win[cur - x]) {
                win[cur] = true;
                break;
            }
        }
    }
    return win[n];
}
Time: O(n²) DP · O(1) parity Space: O(n) DP · O(1) parity