Card shuffles: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Fix Perl6 -> Raku in comments)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(18 intermediate revisions by 11 users not shown)
Line 1:
[[Category:Games]]
 
{{draft task|Games}}{{clarified-review}}
 
Line 32 ⟶ 31:
 
Allow for "human errors" of imperfect cutting and interleaving.
<br><br>
 
Related tasks:
* [[Playing cards]]
* [[Deal cards_for_FreeCell]]
* [[War Card_Game]]
* [[Poker hand_analyser]]
* [[Go Fish]]
=={{header|APL}}==
 
If we generate a deck by
 
<syntaxhighlight lang="apl">
deck ← ⊂[1](52⍴'A23456789TJQK'),[0.5](13⍴'S'),(13⍴'H'),(13⍴'D'),(13⍴'C')
</syntaxhighlight>
 
Then a generated deck looks like
 
<syntaxhighlight lang="apl">
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>
 
Sorting a deck merely requires generating 52 unique random nunmbers from 1 to 52.
 
<syntaxhighlight lang="text">
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
</syntaxhighlight>
=={{header|C}}==
{{trans|Modula-2}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 96 ⟶ 120:
 
while (lp < cutPoint && rp < size) {
/* Allow for an imperfect riffling so that more than one card can come from the same side in a row
biasedcan towardscome from the same side within morea cards.row Removebiased towards the IF statement for perfect riffling. */side
with more cards. Remove the IF statement for perfect riffling.
*/
bound = (cutPoint - lp) * 50 / (size - rp);
if (random(0, 50) >= bound) {
Line 138 ⟶ 164:
}
 
/* add them to the cards in the other hand, sometimes to the fron sometimes to the back */
sometimes to the front sometimes to the back */
if (random(0, 10) >= 1) {
/* front most of the time */
Line 207 ⟶ 234:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>Riffle shuffle
Line 227 ⟶ 254:
=={{header|C sharp|C#}}==
{{trans|Java}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 343 ⟶ 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 356 ⟶ 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++}}==
<langsyntaxhighlight lang="cpp">
#include <time.h>
#include <algorithm>
Line 490 ⟶ 516:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 502 ⟶ 528:
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 607 ⟶ 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 623 ⟶ 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 723 ⟶ 747:
})
fmt.Println(deck)
}</langsyntaxhighlight>
 
{{out}}
Line 740 ⟶ 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 756 ⟶ 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 763 ⟶ 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 771 ⟶ 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 778 ⟶ 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 888 ⟶ 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 904 ⟶ 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 973 ⟶ 1,232:
v = collect(1:20)
println("# Default shuffle:\n", v)
println(" -> ", shuffle!(v), "\n")</langsyntaxhighlight>
 
{{out}}
Line 997 ⟶ 1,256:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.51
 
import java.util.Random
Line 1,063 ⟶ 1,322:
shuffle(deck) // shuffles deck in place
println(deck)
}</langsyntaxhighlight>
 
Sample output:
Line 1,079 ⟶ 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 1,145 ⟶ 1,403:
deck2 = overhand(deck2)
print("Sorted deck after one overhand shuffle:")
show(deck2)</langsyntaxhighlight>
{{out}}
<pre>Sorted deck after one riffle shuffle:
Line 1,155 ⟶ 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}}==
<langsyntaxhighlight lang="modula2">MODULE CardShuffles;
FROM FormatString IMPORT FormatString;
FROM RandomNumbers IMPORT Random;
Line 1,354 ⟶ 1,611:
 
ReadChar;
END CardShuffles.</langsyntaxhighlight>
=={{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 1,375 ⟶ 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 1,388 ⟶ 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 Raku 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,423 ⟶ 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|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,479 ⟶ 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,497 ⟶ 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,504 ⟶ 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}}
<langsyntaxhighlight lang="python">import random
 
def riffleShuffle(va, flips):
Line 1,588 ⟶ 1,909:
random.shuffle(nums)
print nums
print</langsyntaxhighlight>
{{out}}
<pre>Riffle shuffle
Line 1,609 ⟶ 1,930:
[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,618 ⟶ 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,759 ⟶ 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,778 ⟶ 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 ) {
<lang perl6>use v6;
 
sub overhand ( @cards ) {
my @splits = roll 10, ^( @cards.elems div 5 )+1;
@cards.rotor( @splits ,:partial ).reverse.flat
Line 1,791 ⟶ 2,108:
sub riffle ( @pile is copy ) {
my @pile2 = @pile.splice: @pile.elems div 2 ;
 
roundrobin(
@pile.rotor( (1 .. 3).roll(7), :partial ),
Line 1,801 ⟶ 2,118:
@cards.=&overhand for ^10;
say @cards;
 
my @cards2 = ^20;
@cards2.=&riffle for ^10;
say @cards2;
 
say (^20).pick(*);</syntaxhighlight>
</lang>
 
=={{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>
<langsyntaxhighlight 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. */
 
Line 1,867 ⟶ 2,183:
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: _=@.1; do j=2 for #-1; _=_ @.j; end /*j*/; L = length(_)
say center( arg(1), L, '═'); say _; say; return /*show deck*/</langsyntaxhighlight>
{{out|output}}
<pre style="font-size:125%">
Line 1,882 ⟶ 2,198:
♣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,902 ⟶ 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,919 ⟶ 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,938 ⟶ 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#}}
<langsyntaxhighlight lang="vbnet">Imports System.Runtime.CompilerServices
Imports System.Text
 
Line 2,058 ⟶ 2,487:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Line 2,071 ⟶ 2,500:
[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 2,083 ⟶ 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