"""
This program explores the non-randomness of the traditional 'faro'
method of card shuffling.  No matter how many cards there are in a
deck, there is always a finite number of faro shuffles that will
restore their original order.  (Of course, a faro shuffle is very hard
to do in practice!)
"""

def faroShuffle(oldDeck, outShuffle=True):
    """
    performs a 'faro' or 'perfect' shuffle

    `oldDeck` (a sequence) is the original deck.  The shuffled deck is
    returned.  Iff `outShuffle` is True, it does an 'out' shuffle (top
    and bottom cards preserved).  If it is False, it does an 'in'
    shuffle.
    """
    # Look how easy Python makes this!
    n = len(oldDeck)
    newDeck = n*[ 0 ] # initializes result
    if outShuffle:
        newDeck[0:n-1:2] = oldDeck[:n//2] # insert left hand
        newDeck[1:n:2]   = oldDeck[n//2:] # insert right hand
    else:
        newDeck[0:n-1:2] = oldDeck[n//2:] # insert left hand
        newDeck[1:n:2]   = oldDeck[:n//2] # insert right hand
    return newDeck


def countShuffles(nCards):
    """
    counts the number of faro shuffles required to restore a deck

    `nCards` is the number of cards in the deck.  It must be an even
    positive int.
    """
    originalDeck = list(range(nCards))
    currentDeck = originalDeck
    shuffleCount = 0
    while True:
        shuffledDeck = faroShuffle(currentDeck)
        shuffleCount += 1
        if shuffledDeck == originalDeck:
            return shuffleCount
        currentDeck = shuffledDeck

if __name__ == '__main__':
    nCards = 52
    print(('The ordering of a deck of %d cards is'
           ' restored after %d faro shuffles.'
           % (nCards, countShuffles(nCards))))
