Card shuffles: Difference between revisions

3,200 bytes added ,  11 months ago
Line 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;
 
"Starting deck:",
"Riffle shuffle with \(iterations) iterations:",
riffle(deck; iterations),
"\nOverhand shuffle with \(iterations) iterations:",
overhand(deck; iterations),
"\nStandard library shuffle with 1 iteration:",
(deck | knuthShuffle) # shuffles deck in place
</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}}
Line 1,136 ⟶ 1,253:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
-> [3, 11, 18, 14, 2, 12, 13, 4, 10, 19, 8, 16, 20, 5, 1, 6, 9, 15, 17, 7]</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.51
2,458

edits