picking element game - algorithm

This is a simple game:
There is a set, A={a1,...,an}, the opponents can choose one of the first or last elements of set, and at the end the one who collect bigger numbers wins. Now say each participants dose his best, what I need to do is write a Dynamic algorithm to estimate their score.
any idea or clue is truly appreciated.

Here's a hint: to write a dynamic programming algorithm, you typically need a recurrence. Given
A={a1,...,an}
The recurrence would look something like this
f(A)= max( f({a1,...,a_n-1}) , f({a2,...,a_n}) )

Actually the recurrence relation given by dfb may not lead to right answer
as it is not leading to the right sub-optimal structure !
Assume the Player A begins the game :
the structure of problem for him is [a1,a2,...an]
After choosing an element , either a1 or an , its player B's turn to play , and then after that move it is player A's move.
So after two moves , Player A's turn will come again and this will be the right sub-problem for him .The right recurrence relation will be
Suppose from i to j elements are left :
A(i,j)= max(min( A(i+1,j-1),A(i+2,j)+a[i] ), min(A(i,j-2),A(i+1,j-1))+a[j])
Refer to the following link :
http://people.csail.mit.edu/bdean/6.046/dp/

EXAMPLE CODE
Here is Python code to compute the optimal score for first and second players.
A=[3,1,1,3,1,1,3]
cache={}
def go(a,b):
"""Find greatest difference between player 1 coins and player 2 coins when choosing from A[a:b]"""
if a==b: return 0 # no stacks left
if a==b-1: return A[a] # only one stack left
key=a,b
if key in cache:
return cache[key]
v=A[a]-go(a+1,b) # taking first stack
v=max(v,A[b-1]-go(a,b-1)) # taking last stack
cache[key]=v
return v
v = go(0,len(A))
n=sum(A)
print (n+v)/2,(n-v)/2
COUNTEREXAMPLE
Note that the code includes a counter example to one of the other answers to this question.
Consider the case [3,1,1,3,1,1,3].
By symmetry, the first players move always leaves the pattern [1,1,3,1,1,3].
For this the sum of even elements is 1+3+1=5, while the sum of odd is 1+1+3=5, so the argument is that from this position the second player will always win 5, and the first player will always win 5, so the first player will win (as he gets 5 in addition to the 3 from the first move).
However, this logic is flawed because the second player can actually get more.
First player takes 3, leaves [1,1,3,1,1,3] (only choice by symmetry)
Second player takes 3, leaves [1,1,3,1,1]
First player takes 1, leaves [1,3,1,1] (only choice by symmetry)
Second player takes 1, leaves [1,3,1]
First player takes 1, leaves [3,1] (only choice by symmetry)
Second player takes 3, leaves [1]
First player takes 1
So overall first player gets 3+1+1+1=6, while second gets 3+1+3=7 and second player wins.
The flaw is that although it is true that the second player can play such that they will win all even or all odd positions, this is not optimal play and they can actually do better than this in some cases.

Actually you do not need dynamic programming, because it is easy to find an explicit solution for the game above.
Case n is even or n = 1.
The second player to move will always lose.
Case n odd and n > 1.
The second player has a winning strategy iff one of the following 2 scenarios happen:
The elements with even index have bigger sum than all the elements with odd index
All odd elements except the last have bigger sum than all the remainings AND
All odd elements except the first have bigger sum than all the remainings.
Proof sketch:
Case n is even or n = 1: Let Sodd and Seven be the sum of all elements with even/odd indexes. Assume that Sodd > Seven, same argument hold otherwise. The first player has a winning strategy, since he can play in such a way that he will get all odd indexed items.
The case n is odd and n > 1 can also be resolved directly. In fact the first player has two options, he can get the first or last element of the set. Of the remaining elements, partition them the two subsets with odd and even indexes; by the argument above, the second player is going to take the subset with largest sum. If you expand the tree game you will end up with the statement above.

Related

Finding better approach of Modified Nim

It is ultimately a game of nim with certain modification.
Rules are as follows :
There are two players A and B.
The game is played with two piles of matches. Initially, the first pile contains N matches and the second one contains M matches.
The players alternate turns; A plays first.
On each turn, the current player must choose one pile and remove a positive number of matches (not exceeding the current number of matches on that pile) from it.
It is only allowed to remove X matches from a pile if the number of matches in the other pile divides X.
The player that takes the last match from any pile wins.
Both players play optimally.
My take :
let us say we have two piles 2 7. we have 3 cases to reduce the second pile to wiz : 2 1 , 2 3 , 2 5 If A is playing optimally he/she will go for 2 3 so that the only chance left for B is to do 2 1 and then A can go for 0 1 and win the game. The crust of the solution being that if A or B ever encounters any situation where it can directly lose in the next step then it will try their best to avoid it and use the situation to their advantage by just leaving at a state 1 step before that losing stage .
But this approach fails for some unknown test cases , is there any better approach to find the winner , or any other test case which defies this logic.
This is a classic dynamic programming problem. First, find a recurrence relationship that describes an outcome of a game in terms of smaller games. Your parameters here are X and Y, where X is the number of matches in one stack and Y in the other. How do I reduce this problem?
Well, suppose it is my turn with X matches, and suppose that Y is divisible by the numbers a1, a2, and a3, while x is divisible by b1, b2, b3. Then, I have six possible turns. The problem reduces to solving for (X-a1, Y) (X-a2, Y) (X-a3,Y), (X,Y-b1), (X,Y-b2), (X, Y-b3). Once these six smaller games are solved, if one of them is a winning game for me, then I make the corresponding move and win the game.
There is one more parameter, which is whose turn it is. This doubles the size of solvable problems.
The key is to find all possible moves, and recur for each of them, keeping a storage of already solved games for efficiency.
The base case needs to be figured out naturally.

Branching Factor and Depth

Question
A simple two-player game involves a pile of N matchsticks and two
players who have alternating turns. In each turn, a player removes 1,
2 or 3 matchsticks from the pile. The player who removes the last
matchstick loses the game.
A) What are the branching factor and depth of the game tree (give a general solution expressed in terms of N)? How large is the search
space?
B) How many unique states are there in the game? For large N what could be done to make the search more efficient?
Answer
A) I said the branching factor would be 3 but I justified this because the player could only ever remove up to 3 matches, meaning our tree would usually have three children. The second part with regards to the depth, I'm not sure.
B) N x 2 where N is the number of matches remaining. I am not sure how we could make the search more efficient though? Maybe introducing Alpha-beta pruning?
A :
For the depth, just imagine what the longest possible game would look like. It is the game that consists of both players only removing 1 match in each turn. Since there are n matches, such a game would take n turns : the tree has depth n.
B :
There are only 2*N states, each of them accessible from 3 states of higher matchstick count. Since the number of matches necessarily goes down as the game goes on, the graph of possible states is a DAG (Directed Acyclic Graph). A dynamic programming method is therefore possible to analyze this game. In the end, you will see that the optimal move only depends on N mod 4, with N the number of remaining matches.
EDIT : Proof idea for the N mod 4 :
Every position is either a losing or a winning position. A losing position is a situation where no matter what you play, if your adversary plays optimally, you will lose. Similarly, a winning position is a situation where if you play the right moves, the adversary cannot win. N=1 is a losing position (by definition of the game). Therefore, N=2,3,4 are winning positions because by removing the right amount of matches you put the adversary in a losing position. N=5 is a losing position because no matter what admissible number of matches you remove, you put the adversary in a winning position. N=6,7,8 are winning positions ... you get the idea.
Now it is just about making this proof formal : take as hypothesis that a position N is a losing position if and only if N mod 4 = 1. If that is true up to some integer k, you can prove that it is true for k+1. It's true up to k = 4 as we showed earlier. By recurrence, it is true for any N.
The state of the game at any time can be described by whose turn it is and the number of matches held by each player. After n moves there are 3^n possible histories, but for large n, many fewer than 3^n possible states, so you can save time by, for example, recognising that you are about to encounter a state that you have already encountered and worked out a value for before.
See also https://en.wikipedia.org/wiki/Nim - if this is Nim, or a variety of Nim, there are efficient strategies already worked out for it.

Interactive game using Prolog, can you solve it? :)

I'm working on a task to develop predicates to help play this two player game outlined below.
Problem
A 2 person game is played with a set of identical stones arranged into a number of heaps. There may be any number of stones and any number of heaps. A move in this game consists of either removing any number of stones from one heap, or removing an equal number of stones from each of 2 heaps. The loser of this game is the player who picks up the last stone.
e.g
three heaps of sizes 3,2,1, there are 10 possible moves, leading to the below states:
Take from first heap only: [2,2,1],[1,2,1],[2,1]
Taking from 2nd heap only: [3,1,1],[3,1]
Taking from the 3rd heap only: [3,2]
Taking from the 1st and 2nd heaps: [2,1,1], [1,1]
Taking from the 1st and 3rd heaps: [2,2]
Taking from the 2nd and 3rd heaps: [3,1]
[3,1] occurs twice because there are three different ways of reaching it in one move.
Task1
Create a predicate move (S1,S2) that upon backtracking returns all states S2 reachable from S1 in one move.
So far what we have
change([_|T],T).
change([H|T],[H1|T]):-
between(1,H,W),
H1 is H-W,
W<H.
change([H|T],[H|T1]):-
change(T,T1).
change2([H|T],[H1|T1]):-
between(0,H,W),
H1 is H-W,
W<H,
change(T,T1).
So this produces results that will take any number of stones from any individual list and currently will take a differing number of stones from differing lists. So currently I cant get it to work where you want to take the same number of stones from differing lists.
I.e if I had [1,4,1,3] I'd like to be able to end up with [4,3].
Any help would be really appreciated on this task :).

Another Nim's Game Variant

Given N binary sequence
Example :
given one sequence 101001 means
player 0 can only choose a position with 0 element and remove the sequence from that position resulting {1 if he choose 2nd element or 101 if he choose 4nd element or 1010 if he choose 5th element}
player 1 can only choose a position with 1 element ans remove the sequence from that position resulting {null if he choose 1st element or 10 if he choose 3rd element or 10100 if he choose 6th element}
now player 0 and player 1 take turn reducing N sequence, on each turn they pick one sequence, pick an element and remove from that position the the end of the chosen sequence, if a player can't make a move, he lose.
Assume both player play optimally, who will win ?
I tried to solve this problem with grundy but i'm unable to reduce the sequence to a grundy number because it both player don't have the same option to move. Can anyone give me a hint to solve this problem ?
btw sorry for my bad english
It's not Nim. This is the game of Blue-red Hackenbush. There's even an online hackenbush calculator which could solve this specific case (just change B and R to 0 and 1), along with this short explanation of the algorithm:
Until a color change, each segment is worth +1 or -1 (depending on whether it is Blue or Red, respectively).
Once a color change occurs, each subsequent segment (regardless of color), is worth half of the previous segment, with a +/- corresponding to the color.
Thus, the string BBRB would be worth +1+1-1/2+1/4=7/4.
So you can compute the value of each sequence. (Let's suppose player 0 is assigned to the positive side, that is, "0" evaluates to +1.) If the sum of these values over all sequences is positive, then player 0 wins. If it's negative, player 1 wins. And if it's 0, then whoever move first loses.
Ok this is my second try
if player X found X at the top of the stack or list X------- he will take it resulting an empty list that it will leave no moves to the other player and X will win
If Player X found Y at as the first element of the list he will lose any way because what ever he choose on the next turn the player Y will take the first element leaving the Player X with empty list and X will lose
like
YXXXXXXXX
if player X chose any X from the list, Y will select the first and win.
Did I get your point or not Yet
Edit: as pointed out following is not an optimal solution.
IMO if there is only one sequence, then the Player whose number starts the sequence shall win the game. This is because at his/her turn, he/she will simply remove the first element resulting in NULL string and so no move for the other player.
For multiple sequences I can't find a better optimal strategy than following:
Now let us assume there are m sequences that start with 1 and k sequences that start with 0. Each player's strategy shall be to quickly finish the other player's winning sequences.
Hence Player 0 shall choose the first zero in the m sequences beginning with 1 and Player 1 shall choose the first one in the k sequences beginning with 0.
The player looses whose winning sequence finishes first.

Proof of Longest Increasing Subsequence using greedy patience sort

I came across the solution that uses Patience sort to obtain the length of the Longest Increasing Subsequence (LIS). http://www-stat.stanford.edu/~cgates/PERSI/papers/Longest.pdf, and here - http://en.wikipedia.org/wiki/Patience_sorting.
The proof that following the greedy strategy actually gives us the length correctly has 2 parts -
proves that the number of piles is at least equal to the length of the LIS.
proves that the number of piles using greedy strategy is at most equal to the LIS.
Thus by virtue of both 1) and 2), the solution gives the length of LIS correctly.
I get the explanation for 1), but I just cannot intuitively realize part 2). Can someone may be use a different example to convince me that this is indeed true. Or, you could even use a different proof technique too.
I just read over the paper and I agree that the proof is a bit, um, terse. (I'd say that it's missing some pretty important steps!)
Intuitively, the idea behind the proof is to show that if you play with the greedy strategy and at the end of the game pick any card in a pile numbered p, you can find an increasing subsequence in the original array whose length is p. If you can prove this fact, then you can conclude that the maximum number of piles produced by the greedy strategy is the length of the longest increasing subsequence.
To formally prove this, we're going to argue that the following two invariants hold at each step:
The top cards in each pile, when read from left to right, are in sorted order.
At any point in time, every card in every pile is part of an increasing subsequence whose length is given by the pile index.
Part (1) is easy to see from the greedy strategy - every element is placed as far to the left as possible without violating the rule that smaller cards must always be placed on top of larger cards. This means that if a card is put into pile p, we are effectively taking a sorted sequence and reducing the value of the pth element to a value that's greater than whatever is in position p - 1 (if it exists).
To see part (2), we'll go inductively. The first placed card is put into pile 1, and it's also part of an increasing subsequence of length 1 (the card by itself). For the inductive step, assume that this property holds after placing n cards and consider the (n+1)st. Suppose that it ends up in pile p. If p = 1, then the claim still holds because this card forms an increasing subsequence of length 1 all by itself. Otherwise, p > 1. Now, look at the card on top of pile p - 1. We know that this card's value is less than the value of the card we just placed, since otherwise we would have placed the card on top of that pile. We also know that the card on top of that pile precedes the card we just placed in the original ordering, since we're playing the cards in order. By our existing invariant, we know that the card on top of pile p - 1 is part of an increasing subsequence of length p - 1, so that subsequence, with this new card added into it, forms an increasing subsequence of length p, as required.

Resources