Another Nim's Game Variant - algorithm

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.

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.

Math Board Game Puzzle?

I am trying to find a solution to this board game problem this is how it goes.
Mike and Bob are playing a board game on an m by n board. The board has at least 3 rows and 3 columns. The bottom row is row 0 and the top row is row m − 1; the left-most column is column 0 and the right-most column is column n − 1.
Mike moves first, then Bob, then Mike, then Bob, etc. until the game is over. The game is over when one of two things happens: Bob wins or Mike wins.
Bob wins if he lands on the same square as Mike before Mike reaches the top row. Note that this winning condition is checked only after Bob moves; Bob can never win right after Mike moves, even if Mike lands on the same square as Bob
Mike wins if Mike reaches the top row before Bob wins, i.e., Mike reaches the top row without Bob
ever landing on the same square as Mike. As soon as Mike reaches the top row, Mike wins (Bob cannot move
anymore).
Mike’s move on each turn is fixed according to the following rule: he goes 1 square up and then, if not already at the
right edge, goes 1 square to the right as well.
Bob, by contrast, has eight choices of move to make on his turn:
1 up, 2 right
1 up, 2 left
1 down, 2 right
1 down, 2 left
2 up, 1 right
2 up, 1 left
2 down, 1 right
2 down, 1 left
Note that some moves may be unavailable depending on Bob’s location; for example, if Bob is already in column
n − 1, then any move that tries to go to the right is not allowed.
Given the starting locations of Mike and Bod, come up with a solution that determines the result of the game, as follows:
If it is possible for Bob to win, then report that Bob can win and give the minimum number of Bob moves required for him to win.
Otherwise, Mike wins; report the number of Bob moves that occur before Mike wins
we can assume that
Mike’s starting location is never in the top row
Bob’s starting location is never the same as Mike’s
we can use any type of methods we like, the only real restriction to solving this problem are mentioned above. How would we approach a question like this.
Notation
First note that Mike has a fixed, predefined movement strategy.
Let us denote by M0, M1, .., Mk the cells that Mike would go through in his path towards the top row. Here M0 is the starting cell of Mike, and Mk is the cell on the top row that Mike would reach if Bob would not intervene.
Additionally, let us denote by B0 the cell where Bob starts from. According to the statement it is guaranteed that B0 is different from M0.
Reformulation
The question is whether there is sequence of i moves for Bob, B0 -> B1 -> .. -> Bi such that Bi = Mi, for an i between 1 and k - 1.
Approach
One possible approach is to generate the list of all possible cells that can be reached in exactly i moves, for any i.
For i = 0, there is a single cell that can be reached by Bob, the starting position B0.
Afterwards, for i = 1, 2, .. k - 1, we should consider every cell that can be reached in i - 1 steps (we already know this set of cells), and perform each legal move for Bob. The resulting list of positions would be the set of cells reachable in i steps.
Now that we found the cells that can be reached in i steps by Bob, we should simply check whether Mi is in that set. If this happens for at least one i between 1 and k - 1, then Bob wins.
Implementation
For efficiency, it is important to make sure that if the same cell is reached from different sources in the same number of steps, i, then the duplicates are stored only once.
This removal of duplicates is essential, because otherwise the size of the list of reachable cells would grow exponentially with i.
One approach would be to maintain an m by n matrix of booleans for each i, specifying whether the respective cell can be reached in i steps. Improvements in terms of memory are possible, such that only the matrix of booleans for the current i is maintained (along with a temporary matrix to help advancing towards the next set), but a little bit more care would be needed in that case.
Old topic, but I feel like puzzling for a moment:
Start by general observations
On a 3 by 3 board Mike wins in exactly 4 starting positions, namey those where Bob has to move to (1, 2) (order of coordinates here m before n, i.e. not common to chess notations) und Mike can move there.
If Bob moves onto Mike's square, Mike can win the very next move or never at all, because he generally needs two moves from Bob's square to Bob's next square.
So as long as Bob moves diagonally it is just a matter of distance and speed (Mike is 50% faster, just calculate distance to Bob's diagonal).
On the right border Mike is 100% faster. He still has to catch up before the top. Plus Mike has no way of winning if both players end up on different colors on one and those each move.

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.

Intresting puzzle

Task definition:
I have a matrix of natural numbers. The task is to find path from the top-left corner of matrix to bottom-right corner of matrix and dial maximum score.
Rules of navigation: if you are located in [i][j] you can move:
a) to [i][j-1], [i][j+1], [i+1][j] cells and dial zero points
b) to [i+1][j+1] and dial matrix[i][j] points
Little example:
Assume you have score 50and matrix
0 3 5 3 2
4 7 2 5 2
4 3 5 2 5
Assume you are in [1][1] cell (matrix[1][1] = 7). You can navigate to:
a) [1][0] cell with 50 score
b) [1][2] cell with 50 score
c) [2][1] cell with 50 score
d) [2][2] cell with 57 score
What a problem:
I solve this task in very slow way...
I try to implement in with help of recursion. It's easy if you just want to find maximum score. Something like
public int loop(int i, int j) {
int left = loop(i, j-1);
int top = loop(i-1, j);
int diagonal = loop(i-1,j-1) + matrix[i-1][j-1];
return maximum(left, top, diagonal);
}
BUT, I want to find a path with maximum score! And it's very time/memory consuming.
Why it's time/memory consuming:
And there is one problem: I need store path-collection and pass it as a parameter to the loop method. But loop method forks on each iteration and I have to copy path-collection thee times an iteration. Otherwise, each of loop forks will modify common path-collection and finally I will have in it all possible paths. I mean if between left, top & diagonal the biggest is left that we must not to include paths linked with top and diagonal.
Question:
How to solve it in right way?
EDIT:
Actually there is no need to find the full path. It only need to find point's in which you dial a score (in which you make a diagonal moves)
You don't need dynamic programming nor brute force for this!
To see why, let's analyze the rules:
You can move in direction j freely (left & right), so there's no reason to be careful about that direction - you can move into the optimial horizontal postion whenever you want.
Once you increase i (down) there's no way back (though you can increase i without gaining points). Each increase of i should net the maximal amount of points.
You gain points by leaving a cell, but you can only ever leave a row once.
That means you can subdivide this problem and do not need dynamic programming: you can move to the optimal j location, then take one diagonal step; repeat until done.
The optimal i step is moving from a non-last cell in a row with the highest value. You can't move from the last cell because there's no diagonal move possible - so if your matrix has only one column (or row for that matter) you'll never gain points. You can't lose points because the values are natural numbers (but if negative numbers were allowed, you can still skip a row).
In more detail, the optimal path is then found by...
Does the matrix have just one column or row? Move right repeatedly without gaining points then end the program. You can't do much here.
find the maximum value in the current row, ignoring the last value.
generate 'j' moves towards a maximally-valued cell, then move diagonally.
If you're not on the last row, go back to step 2.
You're on the last row and cannot gain more points; just generate moves towards the bottom-right corner to finish your path.
That's it!
Note that there may be multiple maximal paths, your problem specification doesn't guarantee a unique solution.
EDIT: If you don't need the actual path, but just the numbers you scored, the algorithm is much easier - remove or disregard the last row and last column, then for each i (row) return the maximum value in that row.
EDIT:
I misread the question to being just moving down and to the right (ie: j could only change to j or j+1.) so this answer is wrong.
You can use dynamic programming to solve this problem. Greedy doesn't exactly work because you can only travel "down and to the right".
The naive dynamic programming solution would essentially "work backwards" in a literal sense and start from the bottom-right and compute max score when starting at that cell.
Starting from the right-left, and from bottom-up, you can compute the best score you can get from that score simply. You do this for the m x n matrix, then you start from the top left and choose the direction that has the max score.

picking element game

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.

Resources