Card shuffles: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (added whitespace to the task's preamble, added a ;Task and ;Bonus section headers, added a Games category.)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(27 intermediate revisions by 12 users not shown)
Line 1:
[[Category:Games]]
{{draft task|Games}}{{clarified-review}}
 
{{draft task|Games}}
 
There are many techniques that people use to shuffle [[Playing cards|cards]] for card games. Some are more effective than others.
Line 16 ⟶ 15:
One iteration of the riffle shuffle is defined as:
# Split the deck into two piles
# Merge the two piles by alternating taking one card from the top orof bottomeither pile in proportion to (the samenumber throughoutof cards remaining in the wholepile. mergeTo start with the probability for both piles will be 26/52 (50-50), ofthen each25/51-26/51 pileetc etc as the riffle progresses.
# The merged deck is now the new "shuffled" deck
 
Line 28 ⟶ 27:
 
;Bonus
Implement other methods described in the Wikipedia article:   [https://wikipedia.org/wiki/Shuffling#Shuffling_techniques|shuffling techniques].
article:   [https://en.wikipedia.org/wiki/Shuffling#Shuffling_techniques card shuffling].
 
Allow for "human errors" of imperfect cutting and interleaving.
<br><br>
 
Related tasks:
=={{header|C++}}==
* [[Playing cards]]
<lang cpp>
* [[Deal cards_for_FreeCell]]
#include <time.h>
* [[War Card_Game]]
#include <algorithm>
* [[Poker hand_analyser]]
#include <iostream>
* [[Go Fish]]
#include <string>
=={{header|APL}}==
#include <deque>
 
If we generate a deck by
 
<syntaxhighlight lang="apl">
class riffle
deck ← ⊂[1](52⍴'A23456789TJQK'),[0.5](13⍴'S'),(13⍴'H'),(13⍴'D'),(13⍴'C')
{
</syntaxhighlight>
public:
void shuffle( std::deque<int>* v, int tm )
{
std::deque<int> tmp;
bool fl;
size_t len;
std::deque<int>::iterator it;
 
Then a generated deck looks like
copyTo( v, &tmp );
 
<syntaxhighlight lang="apl">
for( int t = 0; t < tm; t++ )
AS 2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS AH 2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH AD 2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD AC 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC
{
</syntaxhighlight>
std::deque<int> lHand( rand() % ( tmp.size() / 3 ) + ( tmp.size() >> 1 ) ), rHand( tmp.size() - lHand.size() );
 
Sorting a deck merely requires generating 52 unique random nunmbers from 1 to 52.
std::copy( tmp.begin(), tmp.begin() + lHand.size(), lHand.begin() );
std::copy( tmp.begin() + lHand.size(), tmp.end(), rHand.begin() );
tmp.clear();
 
<syntaxhighlight lang="text">
while( lHand.size() && rHand.size() )
deck[52?52]
{
JD 8C TH 8D KH QH 6S AH 4D JS 5S AD 6H 3H 3D 5C 9C 7C 7S 4C JC 3S KD 9H 3C 4H 2D TD KS TS 7D JH 9D 8H 6D 7H 2H 4S QC AC KC 9S AS QS TC 2C 8S 5D 2S 6C 5H QD
fl = rand() % 10 < 5;
</syntaxhighlight>
if( fl )
=={{header|C}}==
len = 1 + lHand.size() > 3 ? rand() % 3 + 1 : rand() % ( lHand.size() ) + 1;
{{trans|Modula-2}}
else
<syntaxhighlight lang="c">#include <stdio.h>
len = 1 + rHand.size() > 3 ? rand() % 3 + 1 : rand() % ( rHand.size() ) + 1;
#include <stdlib.h>
#include <string.h>
#include <time.h>
 
void init() {
while( len )
srand((unsigned int)time(NULL));
{
}
if( fl )
 
{
int random(int low, int high) {
tmp.push_front( *lHand.begin() );
int diff, val;
lHand.erase( lHand.begin() );
}
else
{
tmp.push_front( *rHand.begin() );
rHand.erase( rHand.begin() );
}
len--;
}
}
 
if(diff lHand.size()= <high 1 )- low;
if (diff == 0) {
return low;
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:
val = rand() % diff;
void copyTo( std::deque<int>* a, std::deque<int>* b )
return val + low;
{
}
for( std::deque<int>::iterator x = a->begin(); x != a->end(); x++ )
 
b->push_back( *x );
void initDeck(int *deck, const int size) {
a->clear();
int i;
for (i = 0; i < size; ++i) {
*deck++ = i + 1;
}
};
 
void writeDeck(const int *deck, const int size) {
class overhand
int i;
{
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.clearprintf("[");
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));
// global - just to make things simpler ---------------------------------------------------
 
std::deque<int> cards;
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) {
void fill()
/* Allow for an imperfect riffling so that more than one card
{
can come from the same side in a row biased towards the side
cards.clear();
with more cards. Remove the IF statement for perfect riffling.
for( int x = 0; x < 20; x++ )
*/
cards.push_back( x + 1 );
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) {
void display( std::string t )
int n, cutSize, mp, op, tp, i;
{
int *otherHand, *temp;
std::cout << t << "\n";
 
for( std::deque<int>::iterator x = cards.begin(); x != cards.end(); x++ )
otherHand = (int *)malloc(size * sizeof(int));
std::cout << *x << " ";
temp = (int *)malloc(size * sizeof(int));
std::cout << "\n\n";
 
for (n = 0; n < passes; ++n) {
mp = 0;
op = 0;
tp = 0;
 
while (mp < size) {
cutSize = random(0, size / 5) + 1;
 
/* grab the next cut up to the end of the cards left in the main hand */
for (i = 0; i < cutSize && mp < size; ++i) {
temp[tp++] = mainHand[mp++];
}
 
/* add them to the cards in the other hand,
sometimes to the front sometimes to the back */
if (random(0, 10) >= 1) {
/* front most of the time */
 
/* move the elements of other hand forward to make room for temp */
for (i = op - 1; i >= 0; --i) {
otherHand[i + tp] = otherHand[i];
}
 
/* copy temp to the front of other hand */
memcpy(otherHand, temp, tp * sizeof(int));
op += tp;
tp = 0;
} else {
/* end sometimes */
for (i = 0; i < tp; ++i, ++op) {
otherHand[op] = temp[i];
}
tp = 0;
}
}
 
/* move the cards back to the main hand */
memcpy(mainHand, otherHand, size * sizeof(int));
}
 
free(otherHand);
free(temp);
}
 
#define SIZE 20
int main( int argc, char* argv[] )
int main() {
{
int deck[SIZE];
srand( static_cast<unsigned>( time( NULL ) ) );
riffle r; overhand o;
 
init();
fill(); r.shuffle( &cards, 10 ); display( "RIFFLE" );
 
fill(); o.shuffle( &cards, 10 ); display( "OVERHAND" );
printf("Riffle shuffle\n");
fill(); std::random_shuffle( cards.begin(), cards.end() ); display( "STD SHUFFLE" );
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;
}</syntaxhighlight>
}
</lang>
{{out}}
<pre>Riffle shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
RIFFLE
[1, 15, 6, 2, 11, 18, 9, 17 205, 3, 4, 7, 16, 13, 8 7, 10 5, 14 12 1 13, 19, 212, 1117, 15 620]
 
Riffle shuffle
OVERHAND
[1, 2, 133, 124, 115, 106, 97, 188, 179, 610, 511, 412, 313, 7 20 1914, 15, 816, 1417, 1618, 119, 20]
[1, 2, 11, 3, 4, 5, 12, 13, 6, 7, 14, 8, 15, 16, 9, 17, 10, 18, 19, 20]
 
Overhand shuffle
STD SHUFFLE
14[1, 4 172, 3, 124, 5 19, 6, 207, 28, 169, 10, 11, 812, 1513, 714, 1315, 1016, 17, 18, 919, 120]
[2, 19, 4, 10, 11, 8, 12, 7, 6, 3, 16, 14, 18, 1, 5, 13, 9, 15, 17, 20]
</pre>
 
Overhand shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[20, 17, 18, 19, 14, 15, 16, 10, 11, 12, 13, 9, 8, 7, 5, 6, 1, 2, 3, 4]</pre>
 
=={{header|C#|C sharp|C#}}==
{{trans|Java}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 297 ⟶ 370:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Line 310 ⟶ 383:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[20, 17, 18, 19, 15, 16, 11, 12, 13, 14, 10, 7, 8, 9, 5, 6, 2, 3, 4, 1]</pre>
=={{header|C++}}==
<syntaxhighlight lang="cpp">
#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();
}
}
};
 
// global - just to make things simpler ---------------------------------------------------
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;
}
</syntaxhighlight>
{{out}}
<pre>
RIFFLE
18 9 17 20 3 4 16 8 7 10 5 14 12 1 13 19 2 11 15 6
 
OVERHAND
2 13 12 11 10 9 18 17 6 5 4 3 7 20 19 15 8 14 16 1
 
STD SHUFFLE
14 4 17 3 12 5 19 6 20 2 16 11 8 15 7 13 10 18 9 1
</pre>
=={{header|D}}==
{{trans|Java}}
<langsyntaxhighlight Dlang="d">import std.container.array;
import std.random;
import std.range;
Line 415 ⟶ 632:
list.randomShuffle();
writeln(list);
}</langsyntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Line 431 ⟶ 648:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[10, 17, 19, 13, 5, 12, 1, 2, 14, 4, 9, 16, 7, 3, 15, 20, 8, 11, 6, 18]</pre>
 
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 531 ⟶ 747:
})
fmt.Println(deck)
}</langsyntaxhighlight>
 
{{out}}
Line 548 ⟶ 764:
[15 16 10 4 7 2 6 18 14 13 17 1 12 3 11 8 19 20 5 9]
</pre>
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class CardShuffles {
private static final Random rand = new Random()
 
static <T> LinkedList<T> riffleShuffle(List<T> list, int flips) {
LinkedList<T> newList = new LinkedList<T>()
 
newList.addAll(list)
 
for (int n = 0; n < flips; n++) {
//cut the deck at the middle +/- 10%, remove the second line of the formula for perfect cutting
int cutPoint = newList.size().intdiv(2) + (rand.nextBoolean() ? -1 : 1) * rand.nextInt((int) (newList.size() * 0.1))
 
//split the deck
List<T> left = new LinkedList<T>()
left.addAll(newList.subList(0, cutPoint))
List<T> right = new LinkedList<T>()
right.addAll(newList.subList(cutPoint, newList.size()))
 
newList.clear()
 
while (left.size() > 0 && right.size() > 0) {
//allow for imperfect riffling so that more than one card can come form the same side in a row
//biased towards the side with more cards
//remove the if and else and brackets for perfect riffling
if (rand.nextDouble() >= ((double) left.size() / right.size()) / 2) {
newList.add(right.remove(0))
} else {
newList.add(left.remove(0))
}
}
 
//if either hand is out of cards then flip all of the other hand to the shuffled deck
if (left.size() > 0) newList.addAll(left)
if (right.size() > 0) newList.addAll(right)
}
return newList
}
 
static <T> LinkedList<T> overhandShuffle(List<T> list, int passes) {
LinkedList<T> mainHand = new LinkedList<T>()
 
mainHand.addAll(list)
for (int n = 0; n < passes; n++) {
LinkedList<T> otherHand = new LinkedList<T>()
 
while (mainHand.size() > 0) {
//cut at up to 20% of the way through the deck
int cutSize = rand.nextInt((int) (list.size() * 0.2)) + 1
 
LinkedList<T> temp = new LinkedList<T>()
 
//grab the next cut up to the end of the cards left in the main hand
for (int i = 0; i < cutSize && mainHand.size() > 0; i++) {
temp.add(mainHand.remove())
}
 
//add them to the cards in the other hand, sometimes to the front sometimes to the back
if (rand.nextDouble() >= 0.1) {
//front most of the time
otherHand.addAll(0, temp)
} else {
//end sometimes
otherHand.addAll(temp)
}
}
 
//move the cards back to the main hand
mainHand = otherHand
}
return mainHand
}
 
static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
println(list)
list = riffleShuffle(list, 10)
println(list)
println()
 
list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
println(list)
list = riffleShuffle(list, 1)
println(list)
println()
 
list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
println(list)
list = overhandShuffle(list, 10)
println(list)
println()
 
list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
println(list)
list = overhandShuffle(list, 1)
println(list)
println()
 
list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
println(list)
Collections.shuffle(list)
println(list)
}
}</syntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[3, 2, 9, 4, 7, 13, 18, 10, 12, 16, 20, 11, 19, 8, 14, 5, 17, 15, 6, 1]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[12, 13, 1, 14, 2, 15, 16, 3, 4, 5, 6, 7, 17, 8, 18, 9, 10, 19, 11, 20]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[3, 8, 14, 10, 9, 6, 12, 15, 2, 16, 19, 17, 20, 18, 13, 11, 1, 5, 7, 4]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[18, 19, 20, 15, 16, 17, 13, 14, 11, 12, 9, 10, 3, 4, 1, 2, 5, 6, 7, 8]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[18, 17, 20, 5, 8, 11, 2, 4, 3, 7, 19, 10, 15, 14, 12, 13, 16, 9, 1, 6]</pre>
=={{header|J}}==
{{eff note|J|({~ ?~@#)}}
 
<langsyntaxhighlight Jlang="j">NB. overhand cut
overhand=: (\: [: +/\ %@%:@# > # ?@# 0:)@]^:[
 
NB. Gilbert–Shannon–Reeds model
riffle=: (({.~+/)`(I.@])`(-.@]#inv (}.~+/))} ?@(#&2)@#)@]^:[</langsyntaxhighlight>
 
The probability of a cut occurring between each pair of cards in this overhand shuffle is proportional to the reciprocal of the square root of the number of cards in the deck.
Line 564 ⟶ 899:
Here are some examples of the underlying selection mechanism in action for a deck of 10 cards:
 
<langsyntaxhighlight Jlang="j"> ([: +/\ %@%:@# > # ?@# 0:) i.10
0 0 0 0 0 0 0 0 1 1
([: +/\ %@%:@# > # ?@# 0:) i.10
Line 571 ⟶ 906:
0 1 1 2 3 3 3 3 4 5
([: +/\ %@%:@# > # ?@# 0:) i.10
0 1 1 1 1 2 2 3 3 3</langsyntaxhighlight>
 
The final step of a cut is to sort the deck in descending order based on the numbers we compute this way.
Line 579 ⟶ 914:
Task examples:
 
<langsyntaxhighlight Jlang="j"> 1 riffle i.20
0 1 2 3 4 5 6 7 8 13 14 9 15 16 17 10 18 11 12 19
10 riffle i.20
Line 586 ⟶ 921:
17 18 19 13 14 15 16 4 5 6 7 8 9 10 11 12 0 1 2 3
10 overhand i.20
15 11 2 4 5 12 16 10 17 19 9 8 6 13 3 18 7 1 0 14</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
Line 696 ⟶ 1,030:
System.out.println(list + "\n");
}
}</langsyntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Line 712 ⟶ 1,046:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[18, 12, 13, 14, 2, 3, 15, 5, 9, 19, 7, 11, 1, 6, 4, 20, 16, 17, 10, 8]</pre>
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
jq currently does not have a built-in PRNG, so this entry will use an external
source of entropy, and specifically /dev/urandom. So a suitable invocation
of jq or gojq would look like this:
<pre>
< /dev/urandom tr -cd '0-9' | fold -w 1 | jq -MRnrc -f card-shuffles.jq
</pre>
<syntaxhighlight lang="jq">
### Preliminaries
# Output: a prn in range(0;$n) where $n is `.`
def prn:
if . == 1 then 0
else . as $n
| ([1, (($n-1)|tostring|length)]|max) as $w
| [limit($w; inputs)] | join("") | tonumber
| if . < $n then . else ($n | prn) end
end;
 
def knuthShuffle:
length as $n
| if $n <= 1 then .
else {i: $n, a: .}
| until(.i == 0;
.i += -1
| (.i + 1 | prn) as $j
| .a[.i] as $t
| .a[.i] = .a[$j]
| .a[$j] = $t)
| .a
end;
 
### Riffle
# input: deck
def riffle(iterations):
((length / 2)|floor) as $mid
| {pile: .}
| reduce range(0; iterations) as $i (.;
(($mid / 10)|floor) as $tenpc
# choose a random number within 10% of midpoint
| ($mid - $tenpc + ((2 * $tenpc + 1)|prn)) as $cut
# split deck into two at cut point
| .deck1 = .pile[0:$cut]
| .deck2 = .pile[$cut:]
| .pile = []
# choose to draw from top or bottom
| ((2|prn) == 1) as $fromTop
| until( (.deck1|length) == 0 or (.deck2|length) == 0;
if $fromTop
then .deck1[0] as $card
| .deck1 |= .[1:]
| .pile += [$card]
| .deck2[0] as $card
| .deck2 |= .[1:]
| .pile += [$card]
else .deck1[-1] as $card
| .deck1 |= .[:-1]
| .pile += [$card]
| .deck2[-1] as $card
| .deck2 |= .[:-1]
| .pile += [$card]
end )
# add any remaining cards to the pile and reverse it
| if (.deck1|length > 0)
then .pile += .deck1
elif (.deck2|length > 0)
then .pile += .deck2
else .
end
| .pile |= reverse # as pile is upside down
)
| .pile;
 
### Overhand
# input: deck
def overhand(iterations):
((length / 5)|floor) as $twentypc
| { pile: .,
pile2: [] }
| reduce range(0; iterations) as $i (.;
until (.pile|length == 0;
([(.pile|length), (1 + ($twentypc|prn))] | min) as $cards
| .pile2 = .pile[0:$cards] + .pile2
| .pile |= .[$cards:]
| .pile += .pile2
| .pile2 = [] )
| .pile ;
 
### Example
def deck: [range(1;21)];
 
def iterations: 10;
 
deck
| "Starting deck:",
"Riffle shuffle with \(iterations) iterations:",
riffle(iterations),
"\nOverhand shuffle with \(iterations) iterations:",
overhand(iterations),
"\nStandard library shuffle with 1 iteration:",
knuthShuffle
</syntaxhighlight>
{{output}}
<pre>
Starting deck:
Riffle shuffle with 10 iterations:
[1,18,17,13,12,16,15,11,19,14,10,8,4,6,7,3,2,20,5,9]
 
Overhand shuffle with 10 iterations:
[2,6,1,10,14,3,4,5,8,7,9,19,11,12,17,16,18,20,13,15]
 
Standard library shuffle with 1 iteration:
[6,9,15,17,19,11,10,7,2,14,18,13,16,8,12,3,5,20,1,4]
</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">function riffleshuffle!(list::Vector, flips::Integer)
len = length(list)
# pre-allocate the left and right part for efficiency
Line 781 ⟶ 1,232:
v = collect(1:20)
println("# Default shuffle:\n", v)
println(" -> ", shuffle!(v), "\n")</langsyntaxhighlight>
 
{{out}}
Line 805 ⟶ 1,256:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.51
 
import java.util.Random
Line 871 ⟶ 1,322:
shuffle(deck) // shuffles deck in place
println(deck)
}</langsyntaxhighlight>
 
Sample output:
Line 887 ⟶ 1,338:
[17, 9, 12, 15, 7, 13, 18, 8, 2, 20, 5, 10, 16, 6, 14, 4, 19, 3, 11, 1]
</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">-- Return a table respresenting a standard deck of cards in order
function newDeck ()
local cards, suits = {}, {"C", "D", "H", "S"}
Line 953 ⟶ 1,403:
deck2 = overhand(deck2)
print("Sorted deck after one overhand shuffle:")
show(deck2)</langsyntaxhighlight>
{{out}}
<pre>Sorted deck after one riffle shuffle:
Line 963 ⟶ 1,413:
5D 6D 7D 8D 9D TD JD QD KD AD QC KC AC 2D 3D 4C 5C 6C 7C 8C 9C TC JC 2C 3C
</pre>
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE CardShuffles;
FROM FormatString IMPORT FormatString;
FROM RandomNumbers IMPORT Random;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
 
PROCEDURE WriteCard(c : CARDINAL);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
FormatString("%c", buf, c);
WriteString(buf)
END WriteCard;
 
PROCEDURE WriteInteger(i : INTEGER);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
FormatString("%02i", buf, i);
WriteString(buf)
END WriteInteger;
 
PROCEDURE WriteIntArray(array : ARRAY OF INTEGER);
VAR i : CARDINAL;
BEGIN
WriteString("[");
FOR i:=0 TO HIGH(array) DO
IF i>0 THEN
WriteString(", ");
END;
WriteInteger(array[i]);
END;
WriteString("]")
END WriteIntArray;
 
(*---------------------------------------*)
 
TYPE Deck_t = ARRAY[0..20] OF INTEGER;
 
PROCEDURE InitDeck(VAR deck : ARRAY OF INTEGER);
VAR i : CARDINAL;
BEGIN
FOR i:=0 TO HIGH(deck) DO
deck[i] := i + 1
END
END InitDeck;
 
PROCEDURE RiffleShuffle(VAR deck : Deck_t; flips : CARDINAL);
VAR
n,cutPoint,nlp,lp,rp,bound : CARDINAL;
nl : Deck_t;
BEGIN
FOR n:=1 TO flips DO
cutPoint := HIGH(deck) / 2;
IF Random(0, 2) > 0 THEN
cutPoint := cutPoint + Random(0, HIGH(deck) / 10);
ELSE
cutPoint := cutPoint - Random(0, HIGH(deck) / 10);
END;
 
nlp := 0;
lp := 0;
rp := cutPoint;
 
WHILE (lp <= cutPoint) AND (rp < HIGH(deck)) DO
(* Allow for an imperfect riffling so that more than one card can come from the same side in a row
biased towards the side with more cards. Remove the IF statement for perfect riffling. *)
bound := (cutPoint - lp) * 50 / (HIGH(deck) - rp);
IF Random(0, 50)>= bound THEN
nl[nlp] := deck[rp];
INC(nlp);
INC(rp);
ELSE
nl[nlp] := deck[lp];
INC(nlp);
INC(lp);
END
END;
WHILE lp <= cutPoint DO
nl[nlp] := deck[lp];
INC(nlp);
INC(lp);
END;
WHILE rp < HIGH(deck) DO
nl[nlp] := deck[rp];
INC(nlp);
INC(rp);
END;
 
deck := nl
END
END RiffleShuffle;
 
PROCEDURE OverhandShuffle(VAR mainHand : Deck_t; passes : CARDINAL);
VAR
n,cutSize,mp,op,tp,i : CARDINAL;
otherHand,temp : Deck_t;
BEGIN
FOR n:=1 TO passes DO
mp := 0;
op := 0;
FOR i:=0 TO HIGH(otherHand) DO
otherHand[i] := 9999
END;
 
WHILE mp < HIGH(mainHand) DO
(* Cut at up to 20% of the way through the deck *)
cutSize := Random(0, HIGH(mainHand) / 5) + 1;
tp := 0;
 
(* Grab the next cut up to the end of the cards left in the main hand *)
i:=0;
WHILE (i < cutSize) AND (mp < HIGH(mainHand)) DO
temp[tp] := mainHand[mp];
INC(tp);
INC(mp);
INC(i);
 
IF mp = HIGH(mainHand) THEN
temp[tp] := mainHand[mp];
INC(tp);
INC(mp);
END
END;
 
(* Add them to the cards in the other hand, sometimes to the front and sometimes to the back *)
IF Random(0, 10) >= 1 THEN
(* otherHand = temp + otherHand *)
 
(* copy other hand elements up by temp spaces *)
i := op;
WHILE (i > 0) AND (op > 0) DO
otherHand[tp + i] := otherHand[i];
DEC(i)
END;
IF op > 0 THEN
otherHand[tp] := otherHand[0]
END;
 
(* copy the elements of temp into the front of other hand *)
FOR i:=0 TO tp-1 DO
otherHand[i] := temp[i]
END
ELSE
(* otherHand = otherHand + temp *)
FOR i:=0 TO tp DO
otherHand[op+i] := temp[i]
END
END;
op := op + tp
END;
 
(* Move the cards back to the main hand *)
mainHand := otherHand
END
END OverhandShuffle;
 
(* Main *)
VAR deck : Deck_t;
BEGIN
WriteString("Riffle shuffle");
WriteLn;
InitDeck(deck);
WriteIntArray(deck);
WriteLn;
RiffleShuffle(deck, 10);
WriteIntArray(deck);
WriteLn;
WriteLn;
 
WriteString("Riffle shuffle");
WriteLn;
InitDeck(deck);
WriteIntArray(deck);
WriteLn;
RiffleShuffle(deck, 1);
WriteIntArray(deck);
WriteLn;
WriteLn;
 
WriteString("Overhand shuffle");
WriteLn;
InitDeck(deck);
WriteIntArray(deck);
WriteLn;
OverhandShuffle(deck, 10);
WriteIntArray(deck);
WriteLn;
WriteLn;
 
WriteString("Overhand shuffle");
WriteLn;
InitDeck(deck);
WriteIntArray(deck);
WriteLn;
OverhandShuffle(deck, 1);
WriteIntArray(deck);
WriteLn;
 
ReadChar;
END CardShuffles.</syntaxhighlight>
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import algorithm, deques, random, sequtils, strutils
 
proc riffle(deck: seq[int]; iterations: Positive): seq[int] =
result = deck
 
for _ in 1..iterations:
let mid = deck.len div 2
let tenPc = mid div 10
# Choose a random number within 10% of midpoint.
let cut = mid - tenPc + rand(2 * tenPc)
# Split deck into two at cut point.
var deck1 = result[0..<cut].toDeque
var deck2 = result[cut..^1].toDeque
result.setLen(0)
let fromTop = bool(rand(1)) # Choose to draw from top or bottom.
while deck1.len > 0 and deck2.len > 0:
if fromTop:
result.add deck1.popFirst
result.add deck2.popFirst
else:
result.add deck1.popLast
result.add deck2.popLast
# Add any remaining cards to the pile and reverse it.
if deck1.len > 0: result.add deck1.toSeq
elif deck2.len > 0: result.add deck2.toSeq
result.reverse()
 
proc overhand(deck: seq[int]; iterations: Positive): seq[int] =
result = deck
var pile: seq[int]
let twentyPc = deck.len div 5
for _ in 1..iterations:
while result.len > 0:
let cards = min(result.len, rand(1..twentyPc))
pile.insert result[0..<cards]
result.delete(0, cards - 1)
result = move(pile)
 
when isMainModule:
 
randomize()
echo "Starting deck:"
var deck = toSeq(1..20)
echo deck.join(" ")
let iterations = 10
echo "\nRiffle shuffle with $# iterations:".format(iterations)
echo riffle(deck, iterations).join(" ")
echo "\nOverhand shuffle with $# iterations:".format(iterations)
echo overhand(deck, iterations).join(" ")
echo "\nStandard library shuffle with one iteration:"
deck.shuffle() # Shuffles deck in place.
echo deck.join(" ")</syntaxhighlight>
 
{{out}}
<pre>Starting deck:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 
Riffle shuffle with 10 iterations:
7 13 18 10 17 5 16 6 20 2 9 12 14 8 19 4 11 1 15 3
 
Overhand shuffle with 10 iterations:
2 9 10 4 6 5 14 12 11 17 19 1 13 16 8 3 7 18 20 15
 
Standard library shuffle with one iteration:
7 9 15 10 1 19 5 14 6 8 4 3 18 17 16 12 13 20 2 11</pre>
=={{header|PARI/GP}}==
Riffle shuffle:
<langsyntaxhighlight lang="parigp">riffle(v)=
{
my(n=#v,k,t,deck=vector(n),left,right);
Line 983 ⟶ 1,698:
vecextract(v, deck);
}
addhelp(riffle, "riffle(v): Riffle shuffles the vector v, following the Gilbert-Shannon-Reeds model.");</langsyntaxhighlight>
 
Overhand shuffle:
<langsyntaxhighlight lang="parigp">overhand(v)=
{
my(u=[],t,n=2*#v\5);
Line 996 ⟶ 1,711:
u;
}
addhelp(overhand, "overhand(v): Overhand shuffles the vector v.");</langsyntaxhighlight>
 
Usage:
<langsyntaxhighlight lang="parigp">riffle([1..52])
overhand([1..52])</langsyntaxhighlight>
{{out}}
<pre>%1 = [1, 2, 3, 21, 4, 22, 23, 5, 24, 25, 26, 6, 27, 28, 29, 30, 7, 31, 32, 33, 34, 35, 36, 8, 37, 38, 39, 40, 9, 10, 11, 12, 41, 42, 43, 13, 44, 45, 14, 46, 47, 48, 15, 16, 17, 49, 50, 18, 51, 19, 20, 52]
%2 = [44, 45, 46, 47, 48, 49, 50, 51, 52, 43, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 23, 24, 25, 26, 27, 28, 29, 30, 31, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 1, 2, 3, 4]</pre>
 
=={{header|Perl}}==
Follows the Perl 6Raku implementation for the overhand shuffle, but uses classic one-liner for riffle.
<langsyntaxhighlight lang="perl">sub overhand {
our @cards; local *cards = shift;
my(@splits,@shuffle);
Line 1,031 ⟶ 1,745:
@cards = 1..20;
riffle(\@cards) for 1..10;
print join ' ', @cards, "\n";</langsyntaxhighlight>
{{out}}
<pre>9 11 5 2 4 14 1 3 8 6 15 13 16 12 19 20 7 18 10 17
1 10 19 9 18 8 17 7 16 6 15 5 14 4 13 3 12 2 11 20</pre>
 
=={{header|Perl 6}}==
 
<lang perl6>use v6;
 
sub overhand ( @cards ) {
my @splits = roll 10, ^( @cards.elems div 5 )+1;
@cards.rotor( @splits ,:partial ).reverse.flat
}
 
sub riffle ( @pile is copy ) {
my @pile2 = @pile.splice: @pile.elems div 2 ;
 
roundrobin(
@pile.rotor( (1 .. 3).roll(7), :partial ),
@pile2.rotor( (1 .. 3).roll(9), :partial ),
).flat
}
 
my @cards = ^20;
@cards.=&overhand for ^10;
say @cards;
 
my @cards2 = ^20;
@cards2.=&riffle for ^10;
say @cards2;
 
say (^20).pick(*);
</lang>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function riffle(sequence s)
<span style="color: #008080;">function</span> <span style="color: #000000;">riffle</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
sequence res = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
integer l = length(s)
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span>
integer r = rand(l)
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
for i=1 to l do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
if r+i<=l then
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">l</span> <span style="color: #008080;">then</span>
res &= s[r+i]
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if i<=r then
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">r</span> <span style="color: #008080;">then</span>
res &= s[i]
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function overhand(sequence s)
<span style="color: #008080;">function</span> <span style="color: #000000;">overhand</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
sequence res = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
integer l = length(s)
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
while length(s) do
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer r = rand(l*0.2)
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">*</span><span style="color: #000000;">0.2</span><span style="color: #0000FF;">)</span>
if r>length(s) then
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
r = length(s)
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res = s[1..r]&res
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">res</span>
s = s[r+1..$]
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
-- to shorten the output, all 2..7 have been removed from the deck
<span style="color: #000080;font-style:italic;">-- to shorten the output, all 2..7 have been removed from the deck</span>
constant DECKSIZE=52-24
<span style="color: #008080;">constant</span> <span style="color: #000000;">DECKSIZE</span><span style="color: #0000FF;">=</span><span style="color: #000000;">52</span><span style="color: #0000FF;">-</span><span style="color: #000000;">24</span>
 
procedure show_deck(sequence s)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_deck</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
for i=1 to DECKSIZE do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">DECKSIZE</span> <span style="color: #008080;">do</span>
integer c = s[i]-1
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">1</span>
-- puts(1,"23456789TJQKA"[remainder(c,13)+1]&"HCDS"[floor(c/13)+1]&" ")
<span style="color: #000080;font-style:italic;">-- puts(1,"89TJQKA23456789TJQKA"[remainder(c,713)+1]&"HCDS"[floor(c/713)+1]&" ")</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"89TJQKA"</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">"HCDS"</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">/</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
puts(1,"\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
show_deck(riffle(tagset(DECKSIZE)))
<span style="color: #000000;">show_deck</span><span style="color: #0000FF;">(</span><span style="color: #000000;">riffle</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">DECKSIZE</span><span style="color: #0000FF;">)))</span>
show_deck(overhand(tagset(DECKSIZE)))
<span style="color: #000000;">show_deck</span><span style="color: #0000FF;">(</span><span style="color: #000000;">overhand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">DECKSIZE</span><span style="color: #0000FF;">)))</span>
show_deck(shuffle(tagset(DECKSIZE)))</lang>
<span style="color: #000000;">show_deck</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">DECKSIZE</span><span style="color: #0000FF;">)))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,116 ⟶ 1,802:
KH TH AH QH 8D JC QC 8C JH 8H 9D KS TD AS KD 8S TC AD TS AC 9C KC 9H QD JD JS 9S QS
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/simul.l")
 
(de riffle (Lst)
Line 1,134 ⟶ 1,819:
(println 'riffle (riffle (range 1 19)) )
(println 'overhand (overhand (range 1 19)) )
(println 'shuffle (shuffle (range 1 19)) )</langsyntaxhighlight>
{{out}}
<pre>
Line 1,141 ⟶ 1,826:
shuffle (5 3 13 15 17 12 14 11 2 1 19 7 6 9 18 8 10 4 16)
</pre>
=={{header|Python}}==
{{trans|D}}
<syntaxhighlight lang="python">import random
 
def riffleShuffle(va, flips):
nl = va
for n in range(flips):
#cut the deck at the middle +/- 10%, remove the second line of the formula for perfect cutting
cutPoint = len(nl)/2 + random.choice([-1, 1]) * random.randint(0, len(va)/10)
 
# split the deck
left = nl[0:cutPoint]
right = nl[cutPoint:]
 
del nl[:]
while (len(left) > 0 and len(right) > 0):
#allow for imperfect riffling so that more than one card can come form the same side in a row
#biased towards the side with more cards
#remove the if and else and brackets for perfect riffling
if (random.uniform(0, 1) >= len(left) / len(right) / 2):
nl.append(right.pop(0))
else:
nl.append(left.pop(0))
if (len(left) > 0):
nl = nl + left
if (len(right) > 0):
nl = nl + right
return nl
 
def overhandShuffle(va, passes):
mainHand = va
for n in range(passes):
otherHand = []
while (len(mainHand) > 0):
#cut at up to 20% of the way through the deck
cutSize = random.randint(0, len(va) / 5) + 1
temp = []
 
#grab the next cut up to the end of the cards left in the main hand
i=0
while (i<cutSize and len(mainHand) > 0):
temp.append(mainHand.pop(0))
i = i + 1
 
#add them to the cards in the other hand, sometimes to the front sometimes to the back
if (random.uniform(0, 1) >= 0.1):
#front most of the time
otherHand = temp + otherHand
else:
otherHand = otherHand + temp
#move the cards back to the main hand
mainHand = otherHand
return mainHand
 
print "Riffle shuffle"
nums = [x+1 for x in range(21)]
print nums
print riffleShuffle(nums, 10)
print
 
print "Riffle shuffle"
nums = [x+1 for x in range(21)]
print nums
print riffleShuffle(nums, 1)
print
 
print "Overhand shuffle"
nums = [x+1 for x in range(21)]
print nums
print overhandShuffle(nums, 10)
print
 
print "Overhand shuffle"
nums = [x+1 for x in range(21)]
print nums
print overhandShuffle(nums, 1)
print
 
print "Library shuffle"
nums = [x+1 for x in range(21)]
print nums
random.shuffle(nums)
print nums
print</syntaxhighlight>
{{out}}
<pre>Riffle shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
[4, 16, 5, 19, 3, 14, 2, 9, 20, 13, 17, 10, 6, 7, 1, 18, 12, 11, 8, 21, 15]
 
Riffle shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
[13, 14, 15, 1, 16, 2, 3, 17, 4, 5, 18, 6, 7, 19, 8, 9, 20, 10, 11, 21, 12]
 
Overhand shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
[21, 12, 5, 16, 7, 2, 15, 14, 20, 6, 8, 11, 13, 1, 4, 17, 19, 9, 3, 18, 10]
 
Overhand shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
[21, 20, 19, 18, 16, 17, 14, 15, 11, 12, 13, 4, 5, 6, 7, 1, 2, 3, 8, 9, 10]
 
Library shuffle
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
[14, 12, 2, 17, 18, 21, 8, 4, 15, 9, 11, 10, 3, 1, 7, 19, 20, 6, 5, 16, 13]</pre>
=={{header|Racket}}==
 
Line 1,150 ⟶ 1,938:
Racket has a built in <code>shuffle</code> function. Frankly, I'd go with that in your own code!
 
<langsyntaxhighlight lang="racket">#lang typed/racket
;; ---------------------------------------------------------------------------------------------------
;; Types and shuffle builder
Line 1,291 ⟶ 2,079:
(printf "wash piles: ~.a~%" (wash-pile-shuffle unshuffled-pack 1))
;; Or there is always the built-in shuffle:
(printf "shuffle: ~.a~%" (shuffle unshuffled-pack)))</langsyntaxhighlight>
 
{{out}}
Line 1,310 ⟶ 2,098:
shuffle: (J♣ 2♠ 4♦ A♦ K♥ 6♦ 5♦ 8♣ 2♦ T♥ 4♠ 3♣ 7♦ 9♠ T♦ J...
</pre>
=={{header|Raku}}==
(formerly Perl 6)
 
<syntaxhighlight lang="raku" line>sub overhand ( @cards ) {
my @splits = roll 10, ^( @cards.elems div 5 )+1;
@cards.rotor( @splits ,:partial ).reverse.flat
}
 
sub riffle ( @pile is copy ) {
my @pile2 = @pile.splice: @pile.elems div 2 ;
roundrobin(
@pile.rotor( (1 .. 3).roll(7), :partial ),
@pile2.rotor( (1 .. 3).roll(9), :partial ),
).flat
}
 
my @cards = ^20;
@cards.=&overhand for ^10;
say @cards;
my @cards2 = ^20;
@cards2.=&riffle for ^10;
say @cards2;
 
say (^20).pick(*);</syntaxhighlight>
 
=={{header|REXX}}==
A little extra effort was put into the '''create''' subroutine to build any sort of deck, even a multiple deck as in canasta and samba (with/without jokers). &nbsp; Adding options for short decks, pinochle, schmear, six-handed &nbsp; '''500''', &nbsp; and the like would be prohibitive and muddy up the code and be distracting.
 
Six-handed 500 has additional cards of: &nbsp; <big> ♣11 &nbsp; ♣12 &nbsp; &nbsp; &nbsp; &nbsp; ♠11 &nbsp; ♠12 &nbsp; &nbsp; &nbsp; ♦11 &nbsp; ♦12 &nbsp; ♦13 &nbsp; &nbsp; &nbsp; ♦11 &nbsp; ♦12 &nbsp; ♦13 </big>
<syntaxhighlight lang="rexx">/*REXX program simulates various types of shuffling a deck of cards (any kind of deck).*/
call create; call show 'new deck' /*build and display a new card deck. */
 
call create; call riffle 1 /*invoke a riffle shuffle (N times). */
call show 'riffle shuffle' /*display the results from last shuffle*/
 
call create; call overhand 1/5 /*invoke overhand shuffle with 20% cuts*/
call show 'overhand shuffle' /*display the results from last shuffle*/
 
call create; call barnYard 13 /*also called a washing machine shuffle*/
call show 'barn yard shuffle' /*display the results from last shuffle*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
create: if 9=='f9'x then suit= "cdhs" /*EBCDIC? Then use letters for suits.*/
else suit= "♣♦♥♠" /* ASCII? " " symbols " " */
jokers= 0 /*number of jokers in the card deck. */
wild= copies("jH jL", jokers) /*a large # of high jokers, low jokers.*/
rank= 'A23456789tJQK' /*t in the rank represents a ten (10).*/
decks= 1 /*the number of decks, building a shoe?*/
$= /*the initial (null) card deck (string)*/
do s=1 for length(suit) /*process each of the card deck suits. */
_= substr(suit, s, 1) /*extract a single suit to build + pips*/
do r=1 for length(rank) /*process each of the card deck pips. */
$= $ _ || substr(rank, r, 1) /*build a card, then append it to deck.*/
end /*r*/ /*Note: some decks have more pips, >13.*/
end /*s*/ /* " " " " " suits, >4.*/
$= space($ subword(wild, 1, jokers) ) /*keep a new card deck for each shuffle*/
$= copies($, decks) /*maybe build multiple decks for a shoe*/
#= words($) /*set the number of cards in the deck. */
/*another entry point for this function*/
build: @.=; do j=1 for words($) /*build an array for the card deck. */
@.j= word($, j) /*construct an card from the deck list.*/
end /*j*/
return $ /*elide the leading blank in the deck. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
?: return random(1, word( arg(1) #, 1) ) /*gen a random number from 1 ──► arg. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
barnYard: do j=1 for arg(1); x=?();
do until y\==x | #<2; y=?()
end /*until*/
parse value @.x @.y with @.y @.x
end /*j*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
riffle: $A= subword($, 1, #%2); $B= subword($, #%2 + 1); $= /*split deck in half*/
do j=1 for max( words($A), words($B) ); $= $ word($A, j) word($B, j)
end /*j*/
$= space($); call build; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
overhand: parse arg pc .; if pc=='' then pc= 1/5; chunk= # * pc % 1; $B=
do while words($)\==0; $B= $B subword($, 1, chunk); $= subword($, chunk +1)
end /*while*/
$= space($B); call build; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: _=@.1; do j=2 for #-1; _=_ @.j; end /*j*/; L = length(_)
say center( arg(1), L, '═'); say _; say; return /*show deck*/</syntaxhighlight>
{{out|output}}
<pre style="font-size:125%">
═════════════════════════════════════════════════════════════════════════new deck══════════════════════════════════════════════════════════════════════════
♣A ♣2 ♣3 ♣4 ♣5 ♣6 ♣7 ♣8 ♣9 ♣t ♣J ♣Q ♣K ♦A ♦2 ♦3 ♦4 ♦5 ♦6 ♦7 ♦8 ♦9 ♦t ♦J ♦Q ♦K ♥A ♥2 ♥3 ♥4 ♥5 ♥6 ♥7 ♥8 ♥9 ♥t ♥J ♥Q ♥K ♠A ♠2 ♠3 ♠4 ♠5 ♠6 ♠7 ♠8 ♠9 ♠t ♠J ♠Q ♠K
 
══════════════════════════════════════════════════════════════════════riffle shuffle═══════════════════════════════════════════════════════════════════════
♣A ♥A ♣2 ♥2 ♣3 ♥3 ♣4 ♥4 ♣5 ♥5 ♣6 ♥6 ♣7 ♥7 ♣8 ♥8 ♣9 ♥9 ♣t ♥t ♣J ♥J ♣Q ♥Q ♣K ♥K ♦A ♠A ♦2 ♠2 ♦3 ♠3 ♦4 ♠4 ♦5 ♠5 ♦6 ♠6 ♦7 ♠7 ♦8 ♠8 ♦9 ♠9 ♦t ♠t ♦J ♠J ♦Q ♠Q ♦K ♠K
 
═════════════════════════════════════════════════════════════════════overhand shuffle══════════════════════════════════════════════════════════════════════
♣A ♣2 ♣3 ♣4 ♣5 ♣6 ♣7 ♣8 ♣9 ♣t ♣J ♣Q ♣K ♦A ♦2 ♦3 ♦4 ♦5 ♦6 ♦7 ♦8 ♦9 ♦t ♦J ♦Q ♦K ♥A ♥2 ♥3 ♥4 ♥5 ♥6 ♥7 ♥8 ♥9 ♥t ♥J ♥Q ♥K ♠A ♠2 ♠3 ♠4 ♠5 ♠6 ♠7 ♠8 ♠9 ♠t ♠J ♠Q ♠K
 
═════════════════════════════════════════════════════════════════════barn yard shuffle═════════════════════════════════════════════════════════════════════
♣A ♣2 ♣3 ♠2 ♥6 ♣6 ♣7 ♣8 ♦8 ♥8 ♣J ♣Q ♣K ♦A ♦2 ♦3 ♦4 ♥t ♦6 ♦7 ♠A ♦9 ♦t ♦J ♦Q ♠t ♥A ♥2 ♣t ♥4 ♠5 ♣5 ♦K ♥Q ♥9 ♦5 ♥J ♥3 ♥K ♣9 ♣4 ♠3 ♠4 ♠K ♠6 ♥7 ♠8 ♠9 ♠7 ♠J ♠Q ♥5
</pre>
=={{header|Ruby}}==
 
Two methods to solve the requirements, and a third one as bonus.
 
<syntaxhighlight lang="ruby">
<lang Ruby>
def riffle deck
left, right = deck.partition{rand(10).odd?}
Line 1,331 ⟶ 2,217:
 
def overhand deck
deck, new_deck = deck.dup, []
s = deck.size
 
new_deck += deck.pop(rand(s * 0.2)) until deck.empty? do
stack = deck[-rand(deck.size * 0.2), deck.size]
new_deck += stack
deck -= stack
end
 
new_deck
end
Line 1,348 ⟶ 2,229:
deck = [*1..20]
 
putsp riffle(deck).inspect
putsp overhand(deck).inspect
putsp bonus(deck).inspect
</syntaxhighlight>
</lang>
=={{header|Scala}}==
{{trans|Java}}
<syntaxhighlight lang="scala">import scala.collection.mutable.ListBuffer
import scala.util.Random
 
object CardShuffles {
val rand = new Random()
 
def riffleShuffle[T](source: List[T], flips: Int): List[T] = {
val list = source.to[ListBuffer]
for (_ <- 1 to flips) {
//cut the deck at the middle +/- 10%, remove the second line of the formula for perfect cutting
val cutPoint = list.size / 2 + (if (rand.nextBoolean()) -1 else 1) * rand.nextInt((list.size * 0.1).toInt)
 
//split the deck
val left = list.slice(0, cutPoint)
val right = list.slice(cutPoint, list.size)
 
list.clear()
while (left.nonEmpty && right.nonEmpty) {
//allow for imperfect riffling so that more than one card can come form the same side in a row
//biased towards the side with more cards
//remove the if and else and brackets for perfect riffling
if (rand.nextDouble() >= (1.0 * left.size / right.size) / 2.0) {
list.append(right.remove(0))
} else {
list.append(left.remove(0))
}
}
 
//if either hand is out of cards then flip all of the other hand to the shuffled deck
if (left.nonEmpty) list.appendAll(left)
if (right.nonEmpty) list.appendAll(right)
}
list.toList
}
 
def overhandShuffle[T](source: List[T], passes: Int): List[T] = {
var mainHand = source.to[ListBuffer]
for (_ <- 1 to passes) {
val otherHand = new ListBuffer[T]
 
while (mainHand.nonEmpty) {
//cut at up to 20% of the way through the deck
val cutSize = rand.nextInt((source.size * 0.2).toInt) + 1
 
val temp = new ListBuffer[T]
 
//grab the next cut up to the end of the cards left in the main hand
var i = 0
while (i < cutSize && mainHand.nonEmpty) {
temp.append(mainHand.remove(0))
i = i + 1
}
 
//add them to the cards in the other hand, sometimes to the front sometimes to the back
if (rand.nextDouble() >= 0.1) {
//front most of the time
otherHand.insertAll(0, temp)
} else {
//end sometimes
otherHand.appendAll(temp)
}
}
 
//move the cards back to the main hand
mainHand = otherHand
}
mainHand.toList
}
 
def main(args: Array[String]): Unit = {
// riffle shuffle
var lst = (1 to 20).toList
println(lst)
var sorted = riffleShuffle(lst, 10)
println(sorted)
println()
 
lst = (1 to 20).toList
println(lst)
sorted = riffleShuffle(lst, 1)
println(sorted)
println()
 
// overhand shuffle
lst = (1 to 20).toList
println(lst)
sorted = overhandShuffle(lst, 10)
println(sorted)
println()
 
lst = (1 to 20).toList
println(lst)
sorted = overhandShuffle(lst, 1)
println(sorted)
println()
 
// builtin
lst = (1 to 20).toList
println(lst)
sorted = Random.shuffle(lst)
println(sorted)
println()
}
}</syntaxhighlight>
{{out}}
<pre>List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
List(13, 10, 7, 14, 6, 17, 9, 18, 5, 2, 11, 12, 8, 3, 20, 19, 15, 16, 1, 4)
 
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
List(10, 11, 12, 1, 2, 3, 4, 5, 13, 6, 14, 15, 16, 17, 18, 7, 19, 8, 20, 9)
 
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
List(5, 20, 16, 8, 1, 13, 2, 10, 17, 12, 15, 4, 19, 7, 18, 14, 11, 3, 6, 9)
 
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
List(20, 18, 19, 14, 15, 16, 17, 10, 11, 12, 13, 8, 9, 5, 6, 7, 1, 2, 3, 4)
 
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
List(1, 14, 12, 8, 15, 19, 4, 18, 11, 16, 13, 3, 2, 17, 10, 5, 9, 7, 6, 20)</pre>
=={{header|Tcl}}==
<syntaxhighlight lang="tcl">
<lang Tcl>
proc riffle deck {
set length [llength $deck]
Line 1,368 ⟶ 2,368:
puts [riffle [list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52]]
puts [overhand [list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52]]
</syntaxhighlight>
</lang>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Runtime.CompilerServices
Imports System.Text
 
Module Module1
 
<Extension()>
Function AsString(Of T)(c As ICollection(Of T)) As String
Dim sb = New StringBuilder("[")
sb.Append(String.Join(", ", c))
Return sb.Append("]").ToString()
End Function
 
Private rand As New Random()
 
Function RiffleShuffle(Of T)(list As ICollection(Of T), flips As Integer) As List(Of T)
Dim newList As New List(Of T)(list)
 
For n = 1 To flips
'cut the deck at the middle +/- 10%, remove the second line of the formula for perfect cutting
Dim cutPoint As Integer = newList.Count / 2 + If(rand.Next(0, 2) = 0, -1, 1) * rand.Next(newList.Count * 0.1)
 
'split the deck
Dim left As New List(Of T)(newList.Take(cutPoint))
Dim right As New List(Of T)(newList.Skip(cutPoint))
 
newList.Clear()
 
While left.Count > 0 AndAlso right.Count > 0
'allow for imperfect riffling so that more than one card can come form the same side in a row
'biased towards the side with more cards
'remove the if And else And brackets for perfect riffling
If rand.NextDouble() >= left.Count / right.Count / 2 Then
newList.Add(right.First())
right.RemoveAt(0)
Else
newList.Add(left.First())
left.RemoveAt(0)
End If
End While
 
'if either hand is out of cards then flip all of the other hand to the shuffled deck
If left.Count > 0 Then
newList.AddRange(left)
End If
If right.Count > 0 Then
newList.AddRange(right)
End If
Next
 
Return newList
End Function
 
Function OverhandShuffle(Of T)(list As ICollection(Of T), passes As Integer) As List(Of T)
Dim mainHand As New List(Of T)(list)
 
For n = 1 To passes
Dim otherhand = New List(Of T)
 
While mainHand.Count > 0
'cut at up to 20% of the way through the deck
Dim cutSize = rand.Next(list.Count * 0.2) + 1
 
Dim temp = New List(Of T)
 
'grab the next cut up to the end of the cards left in the main hand
Dim i = 0
While i < cutSize AndAlso mainHand.Count > 0
temp.Add(mainHand.First())
mainHand.RemoveAt(0)
i = i + 1
End While
 
'add them to the cards in the other hand, sometimes to the front sometimes to the back
If rand.NextDouble() >= 0.1 Then
'front most of the time
temp.AddRange(otherhand)
otherhand = temp
Else
'end sometimes
otherhand.AddRange(temp)
End If
End While
 
'move the cards back to the main hand
mainHand = otherhand
Next
 
Return mainHand
End Function
 
Sub Main()
Dim list = New List(Of Integer)(Enumerable.Range(1, 20))
Console.WriteLine(list.AsString())
list = RiffleShuffle(list, 10)
Console.WriteLine(list.AsString())
Console.WriteLine()
 
list = New List(Of Integer)(Enumerable.Range(1, 20))
Console.WriteLine(list.AsString())
list = RiffleShuffle(list, 1)
Console.WriteLine(list.AsString())
Console.WriteLine()
 
list = New List(Of Integer)(Enumerable.Range(1, 20))
Console.WriteLine(list.AsString())
list = OverhandShuffle(list, 10)
Console.WriteLine(list.AsString())
Console.WriteLine()
 
list = New List(Of Integer)(Enumerable.Range(1, 20))
Console.WriteLine(list.AsString())
list = OverhandShuffle(list, 1)
Console.WriteLine(list.AsString())
Console.WriteLine()
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[1, 5, 15, 8, 3, 7, 17, 12, 14, 6, 19, 18, 13, 16, 2, 20, 11, 10, 4, 9]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[1, 2, 12, 13, 14, 3, 15, 4, 5, 16, 17, 6, 7, 8, 9, 18, 10, 19, 20, 11]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[15, 16, 20, 14, 17, 9, 10, 5, 6, 3, 12, 18, 11, 4, 1, 2, 8, 13, 19, 7]
 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[19, 20, 15, 16, 17, 18, 13, 14, 10, 11, 12, 7, 8, 9, 4, 5, 6, 1, 2, 3]</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="wren">import "random" for Random
 
var r = Random.new()
 
var riffle = Fn.new { |deck, iterations|
var pile = deck.toList
for (i in 0...iterations) {
var mid = (deck.count / 2).floor
var tenpc = (mid / 10).floor
// choose a random number within 10% of midpoint
var cut = mid - tenpc + r.int(2 * tenpc + 1)
// split deck into two at cut point
var deck1 = pile.take(cut).toList
var deck2 = pile.skip(cut).toList
pile.clear()
var fromTop = r.int(2) == 1 // choose to draw from top or bottom
while (deck1.count > 0 && deck2.count > 0) {
if (fromTop) {
pile.add(deck1.removeAt(0))
pile.add(deck2.removeAt(0))
} else {
pile.add(deck1.removeAt(-1))
pile.add(deck2.removeAt(-1))
}
}
// add any remaining cards to the pile and reverse it
if (deck1.count > 0) {
pile.addAll(deck1)
} else if (deck2.count > 0) {
pile.addAll(deck2)
}
pile = pile[-1..0] // as pile is upside down
}
return pile
}
 
var overhand = Fn.new { |deck, iterations|
var pile = deck.toList
var pile2 = []
var twentypc = (deck.count / 5).floor
for (i in 0...iterations) {
while (pile.count > 0) {
var cards = pile.count.min(1 + r.int(twentypc))
pile2 = pile[0...cards] + pile2
pile = pile[cards..-1]
}
pile.addAll(pile2)
pile2.clear()
}
return pile
}
 
System.print("Starting deck:")
var deck = (1..20).toList
System.print(deck)
var iterations = 10
System.print("\nRiffle shuffle with %(iterations) iterations:")
System.print(riffle.call(deck, iterations))
System.print("\nOverhand shuffle with %(iterations) iterations:")
System.print(overhand.call(deck, iterations))
System.print("\nStandard library shuffle with 1 iteration:")
r.shuffle(deck) // shuffles deck in place
System.print(deck)</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
Starting deck:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
 
Riffle shuffle with 10 iterations:
[7, 17, 13, 8, 16, 3, 9, 6, 18, 2, 4, 14, 19, 11, 12, 20, 10, 1, 15, 5]
 
Overhand shuffle with 10 iterations:
[11, 1, 5, 7, 9, 20, 19, 10, 2, 3, 4, 6, 8, 12, 13, 18, 16, 15, 14, 17]
 
Standard library shuffle with 1 iteration:
[9, 16, 2, 12, 8, 20, 13, 5, 4, 18, 17, 6, 11, 19, 1, 3, 14, 7, 10, 15]
</pre>
 
=={{header|zkl}}==
A much better shuffle is List's shuffle method.
<langsyntaxhighlight lang="zkl">fcn riffle(deck){
len,N:=deck.len(),len/2;
newDeck:=N.pump(List,'wrap(n){ return(Void.Write,deck[n],deck[N+n]) });
Line 1,381 ⟶ 2,593:
len,N,piles:=deck.len(),(0.2*len).toInt(),(len.toFloat()/N).ceil().toInt();
piles.pump(List,'wrap(n){ deck[n*N,N] }).reverse().flatten()
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">riffle( [1..19].walk()).println();
overHand([1..19].walk()).println();
[1..19].walk().shuffle().println();</langsyntaxhighlight>
{{out}}
<pre>
9,482

edits