I'd always thought the answer was one in thirteen on the basis that you win if the last card turned up is a king. But then one day while playing clock patience I started thinking along the lines of Ross and Eric - how can you end up with 1/13 when you have to worry about whether a bottom card matches its position? So I wrote a python program to shuffle a pack randomly a million times and play the game. The python program (very inefficient but seems to be effective) produces results similar to these every time it's run:
Won 76921 out of 999700 plays = 0.076944% win rate ~= 1/13 = 0.076923%
Won 76928 out of 999800 plays = 0.076943% win rate ~= 1/13 = 0.076923%
Won 76937 out of 999900 plays = 0.076945% win rate ~= 1/13 = 0.076923%
Won 76939 out of 1000000 plays = 0.076939% win rate ~= 1/13 = 0.076923%
which suggests that the answer 1/13 is correct. Here's my program:
from random import randint
from random import seed
def createpack():
"Creates a pack of cards - four lots of 1-13"
# N.B. there's an extra one named pack[0] which is ignored
pack = range(0,53)
for i in range(1,53):
pack[i] = (pack[i]-1) % 13 + 1
return pack
def shuffle(pack):
"Shuffles the pack of cards"
for i in range(1,53):
j = randint(1,52)
k = pack[j]
pack[j] = pack[i]
pack[i] = k
return pack
def dodeal(pack):
"Deals the pack of cards randomly into 13 sets of 4"
deal = [[0]*4 for i in range(1,14)]
pack = shuffle(pack)
k = 0
for i in range(0,13):
for j in range(0,4):
k += 1
deal[i][j] = pack[k]
return deal
def play(deal):
"Plays out the clock patience game, returning 1 for a win, 0 otherwise"
i = deal[0][0] - 1
deal[0][0] = 0
nc = 0
winning = 1
while (nc < 52) and winning:
nc += 1
j = 0
while (j < 4) and (deal[i][j] == 0) and winning:
j += 1
if (i==0) and (j==4):
if (nc < 52):
winning = 0
else:
k = deal[i][j] - 1
deal[i][j] = 0
i = k
return winning
pack = createpack()
nwon = 0
for nplayed in range(1,1000001):
deal = dodeal(pack)
won = play(deal)
if (won):
nwon += 1
if nplayed % 100 == 0:
print("Won %d out of %d plays = %8.6f%% win rate ~= 1/13 = %8.6f%%" %
(nwon, nplayed, float(nwon) / nplayed, 1.0/13.0))