N% Unfair Coin

Brain Teasers with Coding Study

There is an unfair coin. It tends to land on one side more than on the other.

Make a fair (unbiased) coin from an unfair (biased) coin.

Write a program which provides a solution for above problem statement.

The coding solution was originally published in my book “Brain Teasers with Coding For Data Scientist”. Puzzles from that book are published on this link. Also, check my books “Brain Teasers with Coding For Data Scientist 2: 9 New Computational Puzzles” and “Puzzles with Coding: Puzzles for Everyone” and “Computational Puzzles To Flex Your Brain: 50 original puzzles to sharpen computing mind and mathematical skills at Amazon. For purchasing my books or related queries, feel free to contact me. In these books, you will find interesting brain teasers those are suitable for coders as well as non-coders. Coding solutions are also provided with Python code. So, grab a copy of those books and jump into the world of fascinating and exciting brain teasers.

Solution:

John von Neumann described the procedure like this:

1. Toss the coin twice.

2. If the outcome of both coins is the same (HH or TT), start over and disregard the current toss.

3. If the outcome of both coins is different (HT or TH), take the first coin as the result and forget the second.

Coding Solution:

from random import randint

# Biased function that returns Heads with head_prob% probability and
# Tails with (100-head_prob)% probability
def toss_biased(head_prob):

 # generate random number between 1-100, both inclusive
 r = randint(1, 100) 
 # return Head if we got number between [1 to Head probability], else return tail
 return H if (r <= head_prob) else T

def toss_unbiased(head_prob):
 # difference = 0 in case of HH or TT toss again
 # difference > 0 in case of HT return H
 # difference < 0 in case of TH return T
 difference = toss_biased(head_prob) - toss_biased(head_prob)
 if difference > 0:
    return H
 if difference < 0:
    return T
 return toss_unbiased(head_prob) 

# Generate Fair Results from a Biased Coin
if __name__ == '__main__':

 # Head
 H = 1
 # Tail
 T = 0

 head_prob = int(input("Enter the probability of getting Head:"))
 if(head_prob <1 or head_prob >99):
     print("Enter probability between 1 & 99")
     exit()
 if(head_prob == 50):
     print("No need to apply a solution")
     exit()
     
 print("the probability of getting Head:", head_prob,"%")
 print("the probability of getting Tail:", 100-head_prob,"%")
 head_count = tail_count = 0
 for i in range(10000):
    val = toss_unbiased(head_prob)

    if val == 1:
        head_count += 1
    else:
        tail_count += 1 

 print("the probabilities after applying a solution:")
# Heads with ~50% probability
 print("HEADS% ~", head_count / 100, "%")
#Tails with ~50% probability
 print("TAILS% ~", tail_count / 100, "%")

Note : (Keeping non-coder readers in mind, code optimization may not be fully utilized.)

Test Output 1:
Enter the probability of getting Head:59
the probability of getting Head: 59 %
the probability of getting Tail: 41 %
the probabilities after applying a solution:
HEADS% ~ 50.19 %
TAILS% ~ 49.81 %


Test Output 2:
Enter the probability of getting Head:77
the probability of getting Head: 77 %
the probability of getting Tail: 23 %
the probabilities after applying a solution:
HEADS% ~ 49.8 %
TAILS% ~ 50.2 %