KGS math club/solution 1 1

Revision as of 13:25, 28 June 2008 by Sigmundur (talk | contribs) (New page: Problem (by amkach): Consider the two player game that begins with an even length fixed random sequence of positive integers. Each player, in turn, removes either the first or last of th...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Problem (by amkach):

Consider the two player game that begins with an even length fixed random sequence of positive integers. Each player, in turn, removes either the first or last of the remaining integers, ending when all the integers have been removed. A player's score is the sum of the integers that they removed; the winner is the player with the higher score (with a tie if equal scores). Show that Player One has a non-losing strategy, i.e., can always force a tie or a win.


Solution:

Let the sequence be (x_1 ... x_n). Let p = x_1 - x_2 + x_3 ... - x_n and

   s = score - opponent's score.

Observation: reverse the sequence and p changes to -p.

 The sequence may be reversed at will since this won't
 affect the game.

Strategy: if p >= 0, take the first, else take the last. To be shown: If strategy is followed, regardless what the

 adversary does, always s + p >= 0.

Proof by induction:

 p will always be kept positive (or 0) by reversing the
   sequence before the player 1's move if p < 0.
 1) in the beginning, s = 0  =>  s + p = p >= 0
 2) assume s + p >= 0.
    Since p >= 0 (if p < 0, reverse the sequence and 
      proceed with the proof). Now x_1 should be removed.
   If opponent takes the x_2,

s' = s + x_1 - x_2 and

     p' = x_3 - x_4 ... - x_n, and 

s' + p' = s + p >= 0.

   If opponent takes the x_n, reverse the sequence. Then

s' = s + x_1 - x_n and

     p' = x_n-1 - ... + x_3 - x_2, and

s' + p' = s + p >= 0. In the end, p will be 0, and s + p = s - p >= 0, that is,

 score >= opponent's score. q.e.d.


Here's a python script to put the strategy into an empirical test; should always give score >= 0 (exhaustively test the opponent responses): import random rand = random.randint seq = [] scores = {} for i in range(0, rand(3,6) * 2): seq.append(rand(-20,20)) print seq def play(seq, score): while (seq): sign = 1; sum = 0 for x in seq: sum += sign * x; sign = -sign if sum >= 0: score += seq.pop(0) else: score += seq.pop() play(seq[1:], score - seq[0]) score -= seq.pop() try: scores[score] += 1 except KeyError: scores[score] = 1 play(seq, 0) print "Scores by frequency\nscore freq" scorelist = scores.items() scorelist.sort() for s in scorelist: print " %3d  %3d" % s


And another for a 1000 game series: import random rand = random.randint scores = {} def play(seq, score): while (seq): sign = 1; sum = 0 for x in seq: sum += sign * x; sign = -sign if sum >= 0: score += seq.pop(0) else: score += seq.pop() play(seq[1:], score - seq[0]) score -= seq.pop() try: scores[score] += 1 except KeyError: scores[score] = 1 for i in range(0, 1000): seq = [] for i in range(0, rand(3,6) * 2): seq.append(rand(-10,10)) play(seq, 0) print "Scores by frequency\nscore freq" scorelist = scores.items() scorelist.sort() for s in scorelist: print " %3d  %5d" % s