Why do my results not correspond to my proof?

A few days ago, my teacher posed me the following problem: you are given two envelopes, and in each of them is a randomly chosen integer, such that all integers have the same probability of being chosen. You open one of the envelopes, and then try to guess if the number you have in your hand is greater or smaller than the number in the second envelope. After you guessed, you can then open the second envelope. You will then repeat this game. Find a strategy such that for each of the following experiments, your chances of winning are greater than 50%.

My strategy is the following: if after $$n$$ times, (#times the first envelope was greater) > (#times the second envelope was greater), we predict that for the $$(n+1)$$-th game, the second envelope will be greater and vice-versa.

The reasoning behind this is as follows. For every experiment, assign it the value $$1$$ if the first envelope contains the larger number and $$0$$ if the second envelope is larger. After $$n$$ experiments, the sum of all of them ranges from $$0$$ to $$n$$, with the probability $$\frac{\binom{n}{k}}{2^n}$$ that it is equal to $$k$$. This means that after the $$(n-1)$$-th experiment, we must predict in a way such that if our prediction is correct, the sum after the $$n$$-th experiment will be closer to $$n/2$$.

So here's the problem: I wrote a program to test my hypothesis, and each time I run it (I repeat the experiment 1 million times), the percentage of correct guesses never passes $$50.1$$% and it is often below 50%.

Did I make a mistake somewhere, or is there some other problem ?

Here is the python program for those who are interested:

import random

counter = 0 #counts the number of correct predictions
score = 0 #counts the number of heads/tails

for i in range(1000000):
if score == i/2:
pred = random.choice((0, 1))
elif score < i/2:
pred = 1
else:
pred = 0

res = random.choice((0, 1))
score += res
if pred == res:
counter += 1

print("counter = " + str(counter))
print("score = " + str(score))
print(str(counter/10000)) #percentage of success

• Please clarify “such that all integers have the same probability of being chosen”. There is no uniform probability distribution on the set of all integers. – Hans Lundmark Oct 7 '18 at 8:45
• Sorry, I am kind of new in probability. The teacher said the numbers are chosen "randomly", and since for all $a \in \mathbb{Z}$, the number of integers smaller than $a$ is equal to the number of those that are greater, I thought there is an equal probability each time (like flipping a coin). So maybe I misinterpreted the question. I'm sorry that I'm not sure how to clarify this. – computerdummy Oct 7 '18 at 9:10
• So ask your teacher to clarify. You may also find the following questions relevant: math.stackexchange.com/questions/14167/…, math.stackexchange.com/questions/709984/…, math.stackexchange.com/questions/655972/… – Hans Lundmark Oct 7 '18 at 10:14

There are several issues here. Hans Lundmark has already pointed out a major one. You are picking from "all integers" such that every integer has the same probability. This is simply not possible. There are an infinite number of distinct choices, and if the common probability is $$p$$, then the total probability of picking any integer would be $$\infty \times p = \infty$$, not $$1$$ like it has to be.

Second, your test program does not test this scenario. It is flipping coins, not picking integers.

Thirdly, and this just applies to how you wrote this question: Python is a format-dependent language, but you have not bothered to reproduce that format correctly here, which makes it hard for anyone to interpret your code. If you expect people to help you, you need to be clear. From what you've written, the for loop only includes the if block.

Fourthly, another major point: Your strategy is what's called the "Gambler's Fallacy". I.e., the mistaken belief that past results have any influence on future events. It does not matter if you just - fairly - flipped 50 billion heads in a row on a fair coin. The next flip is just as likely to be a head as it is to be a tail.

(The two "fairs" in that statement are important. If I saw someone flip just 50 heads in a row, I would be practically certain either the coin or their method of flipping was biased, and therefore a head would be far more likely as the next flip. It is only when you know for a fact that the flipping is fair that you can be sure the next flip has equal chances for heads or tails regardless of previous outcomes.)

Fifthly, Random number generators are called "pseudo-random" number generators for a reason. Computers follow well-defined algorithms, which do not allow for actual randomness. There are a few random things that a computer can pick up on, such as timing of external events, like user keypresses. But there are not enough of them to generate many truly random numbers. So they use these few true random numbers as the starting point for calculating a series of numbers that have many of the properties of randomness, but are not truly random. This means that any computer test of probability may show some bias due to the lack of true randomness. About 30 years ago, I once wrote a program in PL/I that used a random integer generator to produce 0s and 1s similar to yours. Upon testing, I found that the "random" sequence it generated was "11110000111100001111000011110000...". While I doubt that Python does so poorly, you should still treat these generators with great care.

Finally, no stategy can predict a series of fair coin tosses with better than 50% expected accuracy. Whatever prediction you make for a given toss, it has exactly 50% chance of coming true, and there is nothing you can do to change that.