#!/usr/bin/env python
# coding: utf-8
# # Appendix: An interactive Jupyter notebook session to accompany: "Penney's game odds from no-arbitrage" by Miller, J.B. (2019)
#
#
#
# see https://github.com/joshua-benjamin-miller/penneysgame for .ipynb and .py files.
#
#
#
# This interactive notebook explores an algorithm that solves a generalized version of Penney's pattern-matching game for a q-sided die ($q\geq 3$), with potentially unequal probabilities.
#
# The solution implements a generalized version of Conway's leading number algorithm , and cross-validates it via simulation.
#
# References
# 1. Miller, J.B. (2019) "Penney's game odds from no-arbitrage", OSF [PDF Download](https://osf.io/47u5a/)
# 2. Li, Shuo-Yen Robert. (1980) A martingale approach to the study of occurrence of sequence patterns in repeated experiments." _the Annals of Probability_, 8(6) 1171-1176. [PDF Download](https://projecteuclid.org/euclid.aop/1176994578)
# 3. Guibas, L. J. & Odlyzko, A. M. (1981), "String overlaps, pattern matching, and nontransitive games",
# _Journal of Combinatorial Theory, Series A_ 30(2), 183--208. [PDF Download](https://core.ac.uk/download/pdf/81142890.pdf)
# 2.
# ### Third party modules and directory check
# In[1]:
import time
import os #for benchmarking
import numpy as np
#in case we need to update user-defined code e.g. importlib.reload(diffP)
import importlib
# In[32]:
current_dir=os.getcwd()
print(current_dir)
for file in os.listdir(current_dir):
if file[-3:]=='.py':
print(file)
# ### Desciption of code in "conway.py"
# In[2]:
import conway #The programs live here
importlib.reload(conway)
#help(conway)
print('Locked and loaded')
# ## Inspect functions
# ### Let's test the generalized Conway leading number
#
# note: In the speccial case of a fair coin flip, this is $2\times \text{Conway Leading Number}$
#
# Conway leading number is an (asymmetric) measure of overlap between two patterns A and B.
#
# AB measures how the leading numbers of B overlap with the trailing numbers of A, as B is shifted to the right (assuming B is not a subpattern of A)
#
# Here is the function:
# In[6]:
help(conway.payoff_to_B_bettors_if_A_occurs_first)
# If A=THH comes first, how much does a player who, on each trial, initiates a asequence of bets on characters according to B=HHH, get paid?
#
# The players that arrive at time T-1 and time T walk out with \$4 and \$2 respectively, for a total of \$6
#
# In[17]:
distribution={'H':.5, 'T':.5}
A = "THH"
B = "HHH"
print(conway.payoff_to_B_bets_if_A_occurs_first(A, B, distribution))
# ### Let's test the generalized Conway leading number algorithm
#
# Here is the function:
# In[18]:
help(conway.oddsAB)
# What are the odds that that pattern A=HTH precedes pattern B=TTH?
#
# In the case that A occurs before B, i.e we compare the trailing characters of $A\cdot$
# * $AA=8+0+2=10$ (the $A$-bets initiated at $T-2$ and $T$ are winners)
# * $AB=0+0+0=0$ (the $B$-bets never win)
#
# In the case that B occurs before A, i.e we compare the trailing characters of $B\cdot$
# * $BB=8+0+0=8$ (the $B$-bet inititiated at $T-2$ is a winner)
# * $BA=0+0+2=2$ (the $A$-bet initiated at $T$ is a winner)
#
# so odds against $A$ occuring before $B$ are ${AA-AB}:{BB-BA} = 10:6$, or $5:3$
#
# this translates to a probability that $A$ occurs first equal to $3/8$
#
# Let's check this below:
# In[19]:
distribution={'H':.5, 'T':.5}
A = "HTH"
B = "TTH"
print('odds against A = [chances against, chances in favor] = ',conway.oddsAB(A, B, distribution))
print('probability A occurs before B = ', conway.probAB(A, B, distribution))
# ## Cross-Validating the code.
#
#
# ### Replicating original Penney's Game odds (patterns of length 3)
#
# Let's create the table, the probability the row pattern comes before the column pattern, and cross-validate with table from Gardner
#
# In[97]:
from fractions import Fraction
pH = .5
pT = 1-pH
distribution={'H':pH, 'T':pT}
k = 3
#initialize the globals within the module
conway.list_pattern=['-']*k
conway.patterns = []
#build the patterns
help(conway.all_patterns)
conway.all_patterns(k,distribution)
patterns = conway.patterns
print("all patterns of length",k,"= ",patterns)
row = 0
print("-" * 70)
print("", end='\t')
print(*patterns, sep='\t')
while row < 8:
col = 0
print(patterns[row],end='\t')
while col <= 7:
r='\t'
if col ==7:
r='\n'
if patterns[row]==patterns[col]:
print('', end=r)
else:
o=conway.oddsAB(patterns[row],patterns[col], distribution)
F = Fraction(int(o[1]),int(o[0]+o[1]))
N = F.numerator
D = F.denominator
print(N,"/",D,end=r)
col += 1
row += 1
print("-" * 70)
# Gardner's table (they match):
#
#
#
# ### Cross-validate the odds function by simulation
#
# here is the simulation function:
# In[11]:
help(conway.simulate_winrates_penney_game)
# Cross-validate the simple case
# In[258]:
distribution={'H':.5, 'T':.5}
A = "HTH"
B = "TTH"
p = conway.probAB(A,B,distribution)
wait = conway.expected_waiting_time(A,B,distribution)
N=10000
np.random.seed(0)
prop, average_n_flips= conway.simulate_winrates_penney_game(A,B,distribution,N)
print('Pr(A