Perfect Shuffle

Photo via Good Free Photos

Perfect shuffle is a programming exercise that poses the question: If you split a deck of cards perfectly in half  and shuffle them with a perfect interleave, so that the first card of the half-deck on the left is always the top card, how many shuffles will it take until they return to their original order?

I encountered Perfect Shuffle the other night at a code kata held by the local Python group at GSU in Atlanta, GA. How could a room full of really smart, albeit new, programmers take 2 hours and still not come up with a perfect solution?  I admit I was there.  The next day, after thinking about it and checking on two questions I had about lists, I came up with the solution below which  is neither long nor hard.

Everything I needed to know was on page two of Big Daddy’s General Python Toolbox (#1).  All those methods collected below “LISTS” are not for decoration and you can NOT treat a list like it is a string!

Give it a shot for yourself.  Here is my take:


'''
PERFECT SHUFFLE
Perfect shuffle is a programming exercise that poses the question:
if you split a deck of cards perfectly in half and shuffle them with a
perfect interleave so that the first card on the left is always the top
card, how many shuffles will it take until they return to their original
order?
How could a room full of really smart new programmers take 2 hours
and still not come up with a solution?
'''

# create deck
deck=[]
newdeck=[]
for i in range(52):
    deck.append(i+1)
    olddeck=deck.copy()
cyclecount=0

# shuffle function
def shuffle():
    newdeck.clear()
    for i in range(0,26):
        newdeck.append(olddeck[i])
        newdeck.append(olddeck[i+26])
    olddeck.clear()

decks_equal=False
while decks_equal==False:
    cyclecount+=1
    shuffle()
    if deck==newdeck:
        decks_equal=True
        print("Decks in sync at cycle: ", str(cyclecount))
        print("original deck: \n "+ str(deck))
        print("reshuffled deck: \n" + str(newdeck))
    else:
        olddeck.clear()
        olddeck=newdeck.copy()