# https://www.youtube.com/watch?v=rd-yH8hzTLs
'''
In this simulation the astrological signs are represented with the numbers
0 - 11. The position in the array where the signs are randomly stored define
each person and a sign is considered corretly assigned when the number of the
astrological sign is the same as the position in the array.
Example:
position: 0 1 2 3 4 5 6 7 8 9 10 11
array: [3, 6, 4, 2, 1, 5, 7, 0, 8, 9, 11, 10]
^ ^ ^
There are three correct assignments.
'''
from matplotlib import pyplot as plt
from random import random, shuffle
# The number of times to perform the experiment
iterations = 100000
# This is the probability that a given sign will swtich with another to end up
# in the correct place. This simulates the astrologer's intuition when he ask
# the participants questions.
human_factor_probability = 0.28
number_of_signs = 12
# Array for counting number of correct guesses (0 - 12)
correctness = [0] * (number_of_signs + 1)
for i in range(0, iterations):
# Assign the zodiac signs randomly to the persons
signs = [i for i in range(number_of_signs)]
shuffle(signs)
# Allow the signs to switch back to the correct position according to the
# psycological probability
for i, s in enumerate(signs):
if s != i and random() <= human_factor_probability:
signs[i], signs[s] = signs[s], signs[i]
# Count the correct assignments and note it in the correctness array
correct_guesses = sum(1 for z in signs if z == signs[z])
correctness[correct_guesses] += 1
plt.plot(correctness, '-')
plt.title('Human factor probability: {}'.format(human_factor_probability))
plt.xlabel('Correct number of guesses')
plt.ylabel('Occurrences out of {} iterations'.format(iterations))
plt.show()
# Print the probablities for getting the different number of correct guesses
for i, count in enumerate(correctness):
print('Probablity for {} correct guesses: {}'.format(i, count / iterations))
# Average number of correct guesses per round calculated as the centre of mass
# of the correctness array
print('Average correct guesses: {}'.format(
sum(i * count for i, count in enumerate(correctness)) / sum(correctness)))