Task: Card shuffles
C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void init() {
    srand((unsigned int)time(NULL));
}

int random(int low, int high) {
    int diff, val;

    diff = high - low;
    if (diff == 0) {
        return low;
    }

    val = rand() % diff;
    return val + low;
}

void initDeck(int *deck, const int size) {
    int i;
    for (i = 0; i < size; ++i) {
        *deck++ = i + 1;
    }
}

void writeDeck(const int *deck, const int size) {
    int i;

    printf("[");
    if (size > 0) {
        printf("%d", *deck++);
    }
    for (i = 1; i < size; ++i) {
        printf(", %d", *deck++);
    }
    printf("]");
}

void riffleShuffle(int * const deck, const int size, int flips) {
    int n, cutPoint, nlp, lp, rp, bound;
    int *nl;

    nl = (int *)malloc(size * sizeof(int));

    for (n = 0; n < flips; ++n) {
        cutPoint = size / 2;
        if (random(0, 2) > 0) {
            cutPoint = cutPoint + random(0, size / 10);
        } else {
            cutPoint = cutPoint - random(0, size / 10);
        }

        nlp = 0;
        lp = 0;
        rp = cutPoint;

        while (lp < cutPoint && rp < size) {
            
            bound = (cutPoint - lp) * 50 / (size - rp);
            if (random(0, 50) >= bound) {
                nl[nlp++] = deck[rp++];
            } else {
                nl[nlp++] = deck[lp++];
            }
        }
        while (lp < cutPoint) {
            nl[nlp++] = deck[lp++];
        }
        while (rp < size) {
            nl[nlp++] = deck[rp++];
        }

        memcpy(deck, nl, size * sizeof(int));
    }

    free(nl);
}

void overhandShuffle(int * const mainHand, const int size, int passes) {
    int n, cutSize, mp, op, tp, i;
    int *otherHand, *temp;

    otherHand = (int *)malloc(size * sizeof(int));
    temp = (int *)malloc(size * sizeof(int));

    for (n = 0; n < passes; ++n) {
        mp = 0;
        op = 0;
        tp = 0;

        while (mp < size) {
            cutSize = random(0, size / 5) + 1;

            
            for (i = 0; i < cutSize && mp < size; ++i) {
                temp[tp++] = mainHand[mp++];
            }

            
            if (random(0, 10) >= 1) {
                

                
                for (i = op - 1; i >= 0; --i) {
                    otherHand[i + tp] = otherHand[i];
                }

                
                memcpy(otherHand, temp, tp * sizeof(int));
                op += tp;
                tp = 0;
            } else {
                
                for (i = 0; i < tp; ++i, ++op) {
                    otherHand[op] = temp[i];
                }
                tp = 0;
            }
        }

        
        memcpy(mainHand, otherHand, size * sizeof(int));
    }

    free(otherHand);
    free(temp);
}

#define SIZE 20
int main() {
    int deck[SIZE];

    init();

    printf("Riffle shuffle\n");
    initDeck(deck, SIZE);
    writeDeck(deck, SIZE);
    printf("\n");
    riffleShuffle(deck, SIZE, 10);
    writeDeck(deck, SIZE);
    printf("\n\n");

    printf("Riffle shuffle\n");
    initDeck(deck, SIZE);
    writeDeck(deck, SIZE);
    printf("\n");
    riffleShuffle(deck, SIZE, 1);
    writeDeck(deck, SIZE);
    printf("\n\n");

    printf("Overhand shuffle\n");
    initDeck(deck, SIZE);
    writeDeck(deck, SIZE);
    printf("\n");
    overhandShuffle(deck, SIZE, 10);
    writeDeck(deck, SIZE);
    printf("\n\n");

    printf("Overhand shuffle\n");
    initDeck(deck, SIZE);
    writeDeck(deck, SIZE);
    printf("\n");
    overhandShuffle(deck, SIZE, 1);
    writeDeck(deck, SIZE);
    printf("\n\n");

    return 0;
}

C++: #include <time.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <deque>


class riffle
{
public:
    void shuffle( std::deque<int>* v, int tm )
    {
        std::deque<int> tmp;
	bool fl;
	size_t len;
	std::deque<int>::iterator it;

	copyTo( v, &tmp );

	for( int t = 0; t < tm; t++ )
	{
	    std::deque<int> lHand( rand() % ( tmp.size() / 3 ) + ( tmp.size() >> 1 ) ), rHand( tmp.size() - lHand.size() );

	    std::copy( tmp.begin(), tmp.begin() + lHand.size(), lHand.begin() );
	    std::copy( tmp.begin() + lHand.size(), tmp.end(), rHand.begin() );
	    tmp.clear();

	    while( lHand.size() && rHand.size() )
	    {
		fl = rand() % 10 < 5;
		if( fl )
    		    len = 1 + lHand.size() > 3 ? rand() % 3 + 1 : rand() % ( lHand.size() ) + 1;
		else
		    len = 1 + rHand.size() > 3 ? rand() % 3 + 1 : rand() % ( rHand.size() ) + 1;

		while( len )
		{
		    if( fl ) 
		    {
			tmp.push_front( *lHand.begin() );
			lHand.erase( lHand.begin() );
		    }
		    else 
		    {
			tmp.push_front( *rHand.begin() );
			rHand.erase( rHand.begin() );
		    }
		    len--;
		}
	    }

	    if( lHand.size() < 1 ) 
	    {
		for( std::deque<int>::iterator x = rHand.begin(); x != rHand.end(); x++ )
		    tmp.push_front( *x );
	    }
	    if( rHand.size() < 1 ) 
	    {
		for( std::deque<int>::iterator x = lHand.begin(); x != lHand.end(); x++ )
		    tmp.push_front( *x );
	    }
	}
	copyTo( &tmp, v );
    }
private:
    void copyTo( std::deque<int>* a, std::deque<int>* b )
    {
	for( std::deque<int>::iterator x = a->begin(); x != a->end(); x++ )
	    b->push_back( *x );
	a->clear();
    }
};

class overhand
{
public:
    void shuffle( std::deque<int>* v, int tm )
    {
	std::deque<int> tmp;
	bool top;
	for( int t = 0; t < tm; t++ )
	{
	    while( v->size() )
	    {
		size_t len = rand() % ( v->size() ) + 1;
		top = rand() % 10 < 5;
		while( len )
		{
		    if( top ) tmp.push_back( *v->begin() );
		    else tmp.push_front( *v->begin() );
		    v->erase( v->begin() );
		    len--;
		}
	    }
	    for( std::deque<int>::iterator x = tmp.begin(); x != tmp.end(); x++ )
		v->push_back( *x );

	    tmp.clear();
	}
    }
};


std::deque<int> cards;

void fill()
{
    cards.clear();
    for( int x = 0; x < 20; x++ )
	cards.push_back( x + 1 );
}

void display( std::string t )
{
    std::cout << t << "\n";
    for( std::deque<int>::iterator x = cards.begin(); x != cards.end(); x++ )
	std::cout << *x << " ";
    std::cout << "\n\n";
}

int main( int argc, char* argv[] )
{
    srand( static_cast<unsigned>( time( NULL ) ) );
    riffle r; overhand o;	

    fill(); r.shuffle( &cards, 10 ); display( "RIFFLE" );
    fill(); o.shuffle( &cards, 10 ); display( "OVERHAND" );
    fill(); std::random_shuffle( cards.begin(), cards.end() ); display( "STD SHUFFLE" );

    return 0;
}