Task: Card shuffles


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;
}



Go: package main

import (
    "fmt"
    "math/rand"
    "time"
)

func reverse(s []int) {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }
}

func riffle(deck []int, iterations int) []int {
    le := len(deck)
    pile := make([]int, le)
    copy(pile, deck)
    for i := 0; i < iterations; i++ {
        mid := le / 2
        tenpc := mid / 10
        
        cut := mid - tenpc + rand.Intn(2*tenpc+1)
        
        deck1 := make([]int, cut)
        deck2 := make([]int, le-cut)
        copy(deck1, pile[:cut])
        copy(deck2, pile[cut:])
        pile = pile[:0]
        fromTop := rand.Intn(2) 
        for len(deck1) > 0 && len(deck2) > 0 {
            if fromTop == 1 {
                el1 := deck1[0]
                deck1 = deck1[1:]
                el2 := deck2[0]
                deck2 = deck2[1:]
                pile = append(pile, el1, el2)
            } else {
                el1 := deck1[len(deck1)-1]
                deck1 = deck1[:len(deck1)-1]
                el2 := deck2[len(deck2)-1]
                deck2 = deck2[:len(deck2)-1]
                pile = append(pile, el1, el2)
            }
        }
        
        if len(deck1) > 0 {
            pile = append(pile, deck1...)
        } else if len(deck2) > 0 {
            pile = append(pile, deck2...)
        }
        reverse(pile) 
    }
    return pile
}

func overhand(deck []int, iterations int) []int {
    le := len(deck)
    pile := make([]int, le)
    copy(pile, deck)
    pile2 := make([]int, 0)
    twentypc := le / 5
    for i := 0; i < iterations; i++ {
        for len(pile) > 0 {
            cards := 1 + rand.Intn(twentypc)
            if cards > len(pile) {
                cards = len(pile)
            }
            temp := make([]int, cards)
            copy(temp, pile[:cards])
            pile2 = append(temp, pile2...)
            pile = pile[cards:]
        }
        pile = append(pile, pile2...)
        pile2 = pile2[:0]
    }
    return pile
}

func main() {
    rand.Seed(time.Now().UnixNano())
    fmt.Println("Starting deck:")
    deck := make([]int, 20)
    for i := 0; i < 20; i++ {
        deck[i] = i + 1
    }
    fmt.Println(deck)
    const iterations = 10
    fmt.Println("\nRiffle shuffle with", iterations, "iterations:")
    fmt.Println(riffle(deck, iterations))
    fmt.Println("\nOverhand shuffle with", iterations, "iterations:")
    fmt.Println(overhand(deck, iterations))
    fmt.Println("\nStandard library shuffle with 1 iteration:")
    rand.Shuffle(len(deck), func(i, j int) {
        deck[i], deck[j] = deck[j], deck[i] 
    })
    fmt.Println(deck)
}