[Tutor] dovetail shuffle

Lloyd Hugh Allen lha2@columbia.edu
Mon, 02 Apr 2001 20:37:44 -0400


I can't remember whether it was on here or c.l.p that someone was talking 
about shuffling cards; here's my go, based on my recollection of a paper 
I read a bit ago.



--------begin module dovetail.py--------------
import random

def dovetail(deck,splitprecision=2,thumb=2):    
    """Shuffles a deck in a fashion that (hopefully) approximates a "real" shuffle

    This performs something that hopefully approximates the dovetail shuffle
    that I remember reading about two years ago when taking a course from Dave
    Bayer. See Bayer, D. and Diaconis, P. (1992). 'Trailing the dovetail
    shuffle to its lair.' Ann. Appl. Probab. 2 (1992), no. 2 , 294-313."""
    split=-1   #initialize split to a value that guarantees that the while loop goes
    newdeck=[] #initialize the object to be returned at the end of the day
    deck.reverse()  #because we will be popping elements off of the top, instead of the bottom
    if len(deck)>1: #abort if we are given an empty deck
        while split<0 or split>len(deck):   #generate a place to split the deck
            split=len(deck)/2+random.randint(-1*splitprecision,splitprecision)
        left=deck[:-1*split]    #perform the split
        right=deck[split:]
        while len(left)>0 or len(right)>0:
            if len(left)>0: #if there are no cards in the left hand, please don't pop from the left
                for count in range(random.randint(1,min([len(left),thumb+1]))):
                    newdeck.append(left.pop())  #take [1,3] cards (usually) from this hand
            if len(right)>0:
                for count in range(random.randint(1,min([len(right),thumb+1]))):
                    newdeck.append(right.pop())
    return newdeck  #here is your shuffled deck