2

Trying to solve the zero-sum problem described here, where two opponent players at each turn can choose to collect 1, 2 or 3 stones with different values, with the objective of getting more points at the end of the game (and assuming each player is playing optimally).

All presented solutions based on recursion suggest to save at each position in an array (memoization) the points difference between the 2 players, thus deriving the current step as the number of stones taken minus the difference at the following position.

I tried instead a different approach, where I save at each array position the best score any player get starting from that position onward. I then compute a single recursion step as the number of points collected in the current turn plus the best score the same player might get from here on (recursion), taking into account the player are alternating.

My solution fails with some test cases and I wanted to understand if there is a problem with the theory (or if I just have to counter check the implementation).

John L.
  • 39,205
  • 4
  • 34
  • 93
rickyviking
  • 121
  • 1

2 Answers2

1

It is certainly a valid approach to compute "at each array position the best score any player get starting from that position onward".


If a player starts first from position pos, denote that best score as best_score_from_pos(pos, "Alice"). Otherwise, denote that best score as best_score_from_pos(pos, "Bob").

The recurrence relations are
best_score_from_pos(pos, "Bob") = value_sum_from_pos(pos) - best_score_from_pos(pos, "Alice")
and
best_score_from_pos(pos, "Alice") = max(
   stoneValue[pos] + best_score_from_pos(pos+1, "Bob") ,
   stoneValue[pos] + stoneValue[pos+1] + best_score_from_pos(pos+2, "Bob"),
   stoneValue[pos] + stoneValue[pos+1] + stoneValue[pos+2] + best_score_from_pos(pos+3, "Bob") )
when the indices for stoneValue are within bound. If out of bound, replace the corresponding argument for the max function with 0.

If best_score_from_pos(0, "Alice") * 2 > total value, Alice wins.
If best_score_from_pos(0, "Alice") * 2 < total value, Bob wins.
If best_score_from_pos(0, "Alice") * 2 == total value, it is a tie.


It is slightly more complicated to implement the approach above than the "presented solutions" that computes for each position "the points difference between the 2 players". On the other hand, the approach above is somewhat easier to understand.

By the way, my implementation of the approach above passes all tests for the LeetCode problem.

John L.
  • 39,205
  • 4
  • 34
  • 93
0

There is a well known algorithm to solve Zero sum games called MiniMax algorithm. The reason for the failure of your above mentioned approach: Let's say at Alice's turn she took a move to maximize her score in the next turn Bob will try to minimize Alice's score. I think you focussed on only one player's action and didn't take account of other player's action . Score_of_player(Alice,i)=Max(Min(Score_of_player(Bob,i-1))) where i is the number of turns

Dante
  • 29
  • 5