Knuth shuffle: Difference between revisions
→{{header|Uiua}}
(117 intermediate revisions by 50 users not shown) | |||
Line 3:
The [[wp:Knuth shuffle|Knuth shuffle]] (a.k.a. the Fisher-Yates shuffle) is an algorithm for randomly shuffling the elements of an array.
;Task:
Implement the Knuth shuffle for an integer array (or, if possible, an array of any type).
;Specification:
Given an array '''''items''''' with indices ranging from ''0'' to '''''last''''', the algorithm can be defined as follows (pseudo-code):
'''let''' ''j'' = random integer in range ''0'' <math>\leq</math> ''j'' <math>\leq</math> ''i''
'''swap''' ''items''[''i''] '''with''' ''items''[''j'']
;Notes:
* It modifies the input array in-place.
* If that is unreasonable in your programming language, you may amend the algorithm to return the shuffled items as a new array instead.
* The algorithm can also be amended to iterate from left to right, if that is more convenient.
;Test cases:
::::::{| class="wikitable"
|-
! Input array
Line 41 ⟶ 42:
(These are listed here just for your convenience; no need to demonstrate them on the page.)
;Related task:
* [[Sattolo cycle]]
{{Template:Strings}}
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">F knuth_shuffle(&x)
L(i) (x.len - 1 .< 0).step(-1)
V j = random:(0..i)
swap(&x[i], &x[j])
V x = Array(0..9)
knuth_shuffle(&x)
print(‘shuffled: ’x)</syntaxhighlight>
{{out}}
<pre>
shuffled: [0, 5, 7, 1, 3, 8, 4, 6, 9, 2]
</pre>
=={{header|360 Assembly}}==
{{trans|BBC BASIC}}
<
* Knuth shuffle 02/11/2015
KNUTHSH CSECT
Line 99 ⟶ 119:
YREGS
END KNUTHSH
</syntaxhighlight>
{{out}}
<pre>
Line 105 ⟶ 125:
</pre>
=={{header|6502 Assembly}}==
===When the array address is known before runtime===
Runs on easy6502, which has a random number generated memory-mapped at zero page address <code>$FE</code> that updates after every instruction. Works on any array size up to and including 256 bytes. (The code I wrote here prior to this edit was much faster but only worked on arrays of exactly 256 bytes in size). The reason for this was that constraining a random number generator that can produce any 8-bit value to a subset is tricky, since just "rolling again" if out of range will eventually cause the program to lock up if it can't produce a value in range purely by chance. This method uses a bit mask that shifts right as the loop counter decreases to zero, which means that even when only a few bytes still need to be shuffled, the routine is just as quick as it was at the beginning.
<syntaxhighlight lang="6502asm">define sysRandom $fe
define tempMask $ff
define range $00
define tempX $01
define tempY $02
define tempRandIndex $03
define temp $04
CreateIdentityTable:
txa
sta $0200,x
sta $1000,x
inx
bne CreateIdentityTable
;creates a sorted array from 0-255 starting at addr $1000
;also creates another one at $0200 for our test input
lda #1
sta range
ConstrainRNG:
ldx #255
;max range of RNG
lda range
bne outerloop
jmp end
outerloop:
cpx range
bcc continue ;if X >= range, we need to lower X
pha
txa
sta tempX
lsr
cmp range
bcc continue2
tax
pla
jmp outerloop
continue2:
pla
ldx tempX
continue:
ldy range
KnuthShuffle:
lda sysRandom
and $1000,x ;and with range constrictor
tay
lda $0200,y
sty tempRandIndex
sta temp
ldy range
lda $0200,y
pha
lda temp
sta $0200,y
pla
ldy tempRandIndex
sta $0200,y
dec range
jmp ConstrainRNG
end:
brk</syntaxhighlight>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program knuthshuffle64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .asciz "Value : @ \n"
szCarriageReturn: .asciz "\n"
.align 4
TableNumber: .quad 1,2,3,4,5,6,7,8,9,10
.equ NBELEMENTS, (. - TableNumber) / 8
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConversion: .skip 30
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrTableNumber // address number table
mov x1,NBELEMENTS // number of élements
bl knuthShuffle
ldr x2,qAdrTableNumber
mov x3,0
1: // loop display table
ldr x0,[x2,x3,lsl 3]
ldr x1,qAdrsZoneConversion // display value
bl conversion10S // call function
ldr x0,qAdrsMessResult
ldr x1,qAdrsZoneConversion
bl strInsertAtCharInc
bl affichageMess // display message
add x3,x3,1
cmp x3,NBELEMENTS - 1
ble 1b
ldr x0,qAdrszCarriageReturn
bl affichageMess
/* 2e shuffle */
ldr x0,qAdrTableNumber // address number table
mov x1,NBELEMENTS // number of élements
bl knuthShuffle
ldr x2,qAdrTableNumber
mov x3,0
2: // loop display table
ldr x0,[x2,x3,lsl 3]
ldr x1,qAdrsZoneConversion // display value
bl conversion10S // call function
ldr x0,qAdrsMessResult
ldr x1,qAdrsZoneConversion
bl strInsertAtCharInc
bl affichageMess // display message
add x3,x3,1
cmp x3,NBELEMENTS - 1
ble 2b
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsMessResult: .quad sMessResult
qAdrTableNumber: .quad TableNumber
qAdrsZoneConversion: .quad sZoneConversion
/******************************************************************/
/* Knuth Shuffle */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the number of elements */
knuthShuffle:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp x6,x7,[sp,-16]! // save registers
mov x5,x0 // save table address
mov x6,x1 // save number of elements
mov x2,0 // start index
1:
mov x0,0
mov x1,x2 // generate aleas
bl extRandom
ldr x3,[x5,x2,lsl 3] // swap number on the table
ldr x4,[x5,x0,lsl 3]
str x4,[x5,x2,lsl 3]
str x3,[x5,x0,lsl 3]
add x2,x2,1 // next number
cmp x2,x6 // end ?
blt 1b // no -> loop
100:
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret
/******************************************************************/
/* random number */
/******************************************************************/
/* x0 contains inferior value */
/* x1 contains maxi value */
/* x0 return random number */
extRandom:
stp x1,lr,[sp,-16]! // save registers
stp x2,x8,[sp,-16]! // save registers
stp x19,x20,[sp,-16]! // save registers
sub sp,sp,16 // reserve 16 octets on stack
mov x19,x0
add x20,x1,1
mov x0,sp // store result on stack
mov x1,8 // length 8 bytes
mov x2,0
mov x8,278 // call system Linux 64 bits Urandom
svc 0
mov x0,sp // load résult on stack
ldr x0,[x0]
sub x2,x20,x19 // calculation of the range of values
udiv x1,x0,x2 // calculation range modulo
msub x0,x1,x2,x0
add x0,x0,x19 // and add inferior value
100:
add sp,sp,16 // alignement stack
ldp x19,x20,[sp],16 // restaur 2 registers
ldp x2,x8,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
=={{header|ACL2}}==
<
(defun array-swap (name array i j)
Line 130 ⟶ 369:
array
(1- (first (dimensions name array)))
state))</
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC PrintTable(INT ARRAY tab BYTE size)
BYTE i
FOR i=0 TO size-1
DO
PrintF("%I ",tab(i))
OD
PutE()
RETURN
PROC KnuthShuffle(INT ARRAY tab BYTE size)
BYTE i,j
INT tmp
i=size-1
WHILE i>0
DO
j=Rand(i+1)
tmp=tab(i)
tab(i)=tab(j)
tab(j)=tmp
i==-1
OD
RETURN
PROC Main()
BYTE i,size=[20]
INT ARRAY tab(size)
FOR i=0 TO size-1
DO
tab(i)=-50+10*i
OD
PrintE("Original data:")
PrintTable(tab,size)
PutE()
KnuthShuffle(tab,size)
PrintE("Shuffled data:")
PrintTable(tab,size)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Knuth_shuffle.png Screenshot from Atari 8-bit computer]
<pre>
Original data:
-50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140
Shuffled data:
0 60 70 90 80 120 10 50 30 -30 -20 110 -50 140 100 -10 -40 40 20 130
</pre>
=={{header|Ada}}==
This implementation is a generic shuffle routine, able to shuffle an array of any type.
<
type Element_Type is private;
type Array_Type is array (Positive range <>) of Element_Type;
procedure Generic_Shuffle (List : in out Array_Type);</
<
procedure Generic_Shuffle (List : in out Array_Type) is
Line 155 ⟶ 448:
List(K) := T;
end loop;
end Generic_Shuffle;</
An example using Generic_Shuffle.
<
with Generic_Shuffle;
Line 178 ⟶ 471:
Ada.Text_IO.Put(Integer'Image(Integer_List(I)));
end loop;
end Test_Shuffle;</
=={{header|Aime}}==
The shuffle function works on any type (the lists are heterogenous).
<
shuffle(list l)
{
Line 195 ⟶ 488:
}
}
}</
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G}}
<
(
ENTIER (random * ABS (b-a+1) + (a<b|a|b))
Line 212 ⟶ 505:
a[j] := t
OD
);</
<
[20]INT a;
FOR i FROM 1 TO 20 DO a[i] := i OD;
knuth shuffle(a);
print(a)
)</
=={{header|Amazing Hopper}}==
<syntaxhighlight lang="c">
#include <basico.h>
algoritmo
v={},n=19
'0,1,2,3,4,5,6,7,8,9,"\t","\v","\v","A","B","C","D","E","F"' enlistar en 'v'
imprimir ("Original:\n[",v,"]\n\n")
imprimir (rareti( n, #(ceil(rand(n))), n, intercambiar en (v)),\
"Processed:\n[", v,"]\n" )
terminar
</syntaxhighlight>
{{out}}
<pre>
Original:
[0,1,2,3,4,5,6,7,8,9, ,
,
,A,B,C,D,E,F]
Processed:
[F,B, ,1,9,
,2,D,5,6,4,8,C,7,A,
,3,0,E]
</pre>
=={{header|AppleScript}}==
Line 224 ⟶ 545:
===Iteration===
<
set array to {}
Line 237 ⟶ 558:
end repeat
return {unshuffled, shuffled}</
Example:
<
{14, 25, 3, 1, 12, 18, 11, 20, 16, 15, 21, 5, 22, 19, 2, 24, 8, 10, 13, 6, 17, 23, 9, 7, 4}}</
----
Better:
<syntaxhighlight lang="applescript">-- Fisher-Yates (aka Durstenfeld, aka Knuth) shuffle.
on shuffle(theList, l, r)
set listLength to (count theList)
if (listLength < 2) then return array
if (l < 0) then set l to listLength + l + 1
if (r < 0) then set r to listLength + r + 1
if (l > r) then set {l, r} to {r, l}
script o
property lst : theList
end script
repeat with i from l to (r - 1)
set j to (random number from i to r)
set v to o's lst's item i
set o's lst's item i to o's lst's item j
set o's lst's item j to v
end repeat
return theList
end shuffle
local array
set array to {"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliett", "Kilo", "Lima", "Mike"}
-- Shuffle all items (1 thru -1).
shuffle(array, 1, -1)</syntaxhighlight>
{{output}}
''eg.''
<syntaxhighlight lang="applescript">{"Golf", "Foxtrot", "Echo", "Delta", "Kilo", "Charlie", "Mike", "Alpha", "Lima", "Juliett", "India", "Bravo", "Hotel"}</syntaxhighlight>
When a large number of random indices is required, it can actually be faster to create a list of integers and select from these using AppleScript's 'some' specifier than to call the StandardAdditions' 'random number' function repeatedly. But a better solution since Mac OS X 10.11 is to use the system's GameplayKit framework:
<syntaxhighlight lang="applescript">use AppleScript version "2.5" -- OS X 10.11 (El Capitan) or later
use framework "Foundation"
use framework "GameplayKit"
on shuffle(theList, l, r)
set listLength to (count theList)
if (listLength < 2) then return theList
if (l < 0) then set l to listLength + l + 1
if (r < 0) then set r to listLength + r + 1
if (l > r) then set {l, r} to {r, l}
script o
property lst : theList
end script
set rndGenerator to current application's class "GKRandomDistribution"'s distributionWithLowestValue:(l) highestValue:(r)
repeat with i from r to (l + 1) by -1
set j to (rndGenerator's nextIntWithUpperBound:(i))
set v to o's lst's item i
set o's lst's item i to o's lst's item j
set o's lst's item j to v
end repeat
return theList
end shuffle</syntaxhighlight>
----
===Functional composition===
<
-- knuthShuffle :: [a] -> [a]
Line 315 ⟶ 695:
end script
end if
end mReturn</
{{Out}}
e.g.
<
"iota", "kappa", "lambda", "epsilon", "beta", "eta"}</
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
Line 555 ⟶ 936:
</syntaxhighlight>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">knuth: function [arr][
if 0=size arr -> return []
loop ((size arr)-1)..0 'i [
j: random 0 i
tmp: arr\[i]
set arr i arr\[j]
set arr j tmp
]
return arr
]
print knuth []
print knuth [10]
print knuth [10 20]
print knuth [10 20 30]</syntaxhighlight>
=={{header|AutoHotkey}}==
ahk forum: [http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=133 discussion]
<
MsgBox % shuffle("1,2,3,4,5,6,7,8,9")
Line 571 ⟶ 972:
s .= "," . a%A_Index%
Return SubStr(s,2) ; drop leading comma
}</
For Arrays:
[https://www.autohotkey.com/boards/viewtopic.php?f=6&t=79152 to MsgBox it, you can use p()]
[https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array#6274381 (translated from)]
<syntaxhighlight lang="autohotkey">toShuffle:=[1,2,3,4,5,6]
shuffled:=shuffle(toShuffle)
;p(toShuffle) ;because it modifies the original array
;or
;p(shuffled)
shuffle(a)
{
i := a.Length()
loop % i-1 {
Random, j,1,% i
x := a[i]
a[i] := a[j]
a[j] := x
i--
}
return a
}</syntaxhighlight>
=={{header|AutoIt}}==
<syntaxhighlight lang="autoit">
Dim $a[10]
ConsoleWrite('array before permutation:' & @CRLF)
Line 600 ⟶ 1,024:
Next
EndFunc
</syntaxhighlight>
{{out}}
Line 614 ⟶ 1,038:
This example shows how to shuffle such arrays.
The elements can be integers, floating-point numbers, or strings.
<
function shuffle(array, len, i, j, t) {
for (i = len; i > 1; i--) {
Line 634 ⟶ 1,058:
for (i = 1; i < len; i++) printf "%s ", array[i]
printf "%s\n", array[len]
}</
=={{header|BASIC}}==
<
DIM cards(51) AS INTEGER
Line 657 ⟶ 1,081:
PRINT LTRIM$(STR$(cards(L0))); " ";
NEXT
PRINT</
{{out}}
Line 671 ⟶ 1,095:
==={{header|Applesoft BASIC}}===
As mentioned in the Sinclair ZX81 BASIC solution, for very small positive integer values, a string is a much more memory-efficient array, but here is an example of an array with numbers. Line <code>150</code> initializes and prints each element in the array. Line <code>190</code> performs the swap of the elements.
<
110 REM KNUTH SHUFFLE
120 :
Line 683 ⟶ 1,107:
200 FOR I = 1 TO 25
210 PRINT A(I);" ";: NEXT I
220 END</syntaxhighlight>
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1
Line 691 ⟶ 1,114:
<pre>20 5 6 9 15 23 22 8 4 24 7 11 16 21 2 17
14 10 19 13 12 18 1 3 25</pre>
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> cards% = 52
DIM pack%(cards%)
FOR I% = 1 TO cards%
pack%(I%) = I%
NEXT I%
FOR N% = cards% TO 2 STEP -1
SWAP pack%(N%),pack%(RND(N%))
NEXT N%
FOR I% = 1 TO cards%
PRINT pack%(I%);
NEXT I%
PRINT</syntaxhighlight>
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
The [[#GW-BASIC|GW-BASIC]] solution works without any changes.
==={{header|GW-BASIC}}===
{{works with|PC-BASIC|any}}
{{works with|BASICA}}
{{works with|Chipmunk Basic}}
<syntaxhighlight lang="qbasic">100 CLS
110 RANDOMIZE TIMER
120 DIM CARDS(51)
130 PRINT "before:"
140 FOR L0 = 0 TO 51
150 CARDS(L0) = L0
160 PRINT STR$(CARDS(L0));" ";
170 NEXT L0
180 FOR L0 = 51 TO 0 STEP -1
190 CARD = INT(RND(1)*(L0+1))
200 IF CARD <> L0 THEN T = CARDS(CARD) : CARDS(CARD) = CARDS(L0) : CARDS(L0) = T
210 NEXT L0
220 PRINT : PRINT
230 PRINT "after:"
240 FOR L0 = 0 TO 51
250 PRINT STR$(CARDS(L0));" ";
260 NEXT L0
270 PRINT
280 END</syntaxhighlight>
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "Shuffle.bas"
110 RANDOMIZE
120 NUMERIC ARRAY(1 TO 20)
130 CALL INIT(ARRAY)
140 CALL WRITE(ARRAY)
150 CALL SHUFFLE(ARRAY)
160 CALL WRITE(ARRAY)
170 DEF INIT(REF A)
180 FOR I=LBOUND(A) TO UBOUND(A)
190 LET A(I)=I
200 NEXT
210 END DEF
220 DEF WRITE(REF A)
230 FOR I=LBOUND(A) TO UBOUND(A)
240 PRINT A(I);
250 NEXT
260 PRINT
270 END DEF
280 DEF SHUFFLE(REF A)
290 FOR I=UBOUND(A) TO LBOUND(A) STEP-1
300 LET CARD=RND(UBOUND(A)-LBOUND(A))+LBOUND(A)+1
310 IF CARD<>I THEN LET T=A(CARD):LET A(CARD)=A(I):LET A(I)=T
320 NEXT
330 END DEF</syntaxhighlight>
==={{header|Minimal BASIC}}===
<syntaxhighlight lang="qbasic">100 REM Knuth shuffle
110 RANDOMIZE
120 DIM B(51)
130 PRINT "BEFORE:"
140 FOR L0 = 0 TO 51
150 LET B(L0) = L0
160 PRINT B(L0);" ";
170 NEXT L0
180 FOR L0 = 51 TO 0 STEP -1
190 LET C = INT(RND*(L0+1))
200 IF C <> L0 THEN 220
210 GOTO 250
220 LET T = B(C)
230 LET B(C) = B(L0)
240 LET B(L0) = T
250 NEXT L0
260 PRINT
270 PRINT
280 PRINT "AFTER:"
290 FOR L0 = 0 TO 51
300 PRINT B(L0);" ";
310 NEXT L0
320 PRINT
330 END</syntaxhighlight>
==={{header|OxygenBasic}}===
<syntaxhighlight lang="text">uses chaos
uses timeutil
seed=GetTickCount
int i,j
int d[100] 'int array or any other type
...
for i=100 to 1 step -1
j=irnd(1,100)
swap d[i],d[j]
next</syntaxhighlight>
==={{header|QB64}}===
Shuffle and make sure that number does not take its place<br/>
and between cells at least 10% ... Shuffle from Russia
<syntaxhighlight lang="qbasic">
a = 100: DIM d(a): x=0: k=0: t$=CHR$(9): RANDOMIZE TIMER 'Shuffle_RUS.bas
PRINT ,: FOR i = 1 TO a: d(i)=i: NEXT
FOR i = 1 TO 5: PRINT d(i);: NEXT: PRINT ,
FOR i = a-3 TO a: PRINT d(i);: NEXT: z = TIMER
OPEN "b:/control.txt" FOR OUTPUT AS #1 ' ram disk
WHILE x < 1
v = 0: FOR i = 1 TO a
1 m = INT(RND*a)+1: IF ABS(d(i)-d(m)) < .1*a THEN v = v+1: GOTO 1
PRINT #1, ABS(d(i)-d(m)); t$; d(i); t$; d(m); t$; i; t$; m; t$; d(i)/d(m); t$; d(m)/d(i) ' ram disk
t = d(i): d(i) = d(m): d(m) = t
NEXT
s = 0: FOR i = 1 TO a
IF d(i) = i THEN s = s+1 ' : goto 5
NEXT
5 k = k+1: PRINT: PRINT s; v,: IF s=0 THEN x = x+1
FOR i = 1 TO 5
IF d(i) = i THEN PRINT -d(i); ELSE PRINT d(i);
NEXT: PRINT ,
FOR i = a-3 TO a
IF d(i) = i THEN PRINT -d(i); ELSE PRINT d(i);
NEXT
WEND: PRINT: PRINT " = "; k, TIMER-z: END</syntaxhighlight>
==={{header|Sinclair ZX81 BASIC}}===
Line 696 ⟶ 1,254:
The program works with the unexpanded (1k RAM) ZX81.
<
20 LET A$=""
30 FOR I=1 TO 26
Line 709 ⟶ 1,267:
120 PRINT AT 0,I-1;CHR$ (CODE A$(I)+128)
130 PRINT AT 0,J-1;CHR$ (CODE A$(J)+128)
140 NEXT I</
{{out}}
While the program is running, we will see something like this (using lower case as a stand-in for inverse video):
Line 716 ⟶ 1,274:
<pre>lcjbpxekzsaygumwnovfdtiqrh</pre>
==={{header|
{{trans|BASIC}}
<syntaxhighlight lang="qbasic">OPTION BASE 0
RANDOMIZE
DIM cards(51)
PRINT "before:"
FOR L0 = 0 TO
LET
FOR L0 = 51 TO 0 STEP -1
LET card = INT(RND * (L0 + 1))
IF card <> L0 THEN
LET t = cards(lb + L0)
LET cards(lb + L0) = cards(lb + card)
LET cards(lb + card) = t
END IF
NEXT L0
PRINT
PRINT "after:"
FOR L0 = 0 TO 51
PRINT LTRIM$(STR$(cards(L0))); " ";
NEXT L0
END</syntaxhighlight>
{{out}}
<pre>Same as BASIC entry.</pre>
==
I provide a <tt>shuffle()</tt> function. It can only shuffle an array of numbers. It fails if the array has more than 32768 elements. It always shuffles the array named <tt>shuffle[]</tt>; the array is not a function parameter because <tt>bc</tt> passes arrays by copying.
This code requires a <tt>bc</tt> with long names; the test program also requires a <tt>bc</tt> with the <tt>print</tt> statement.
{{works with|OpenBSD bc}}
<
scale = 0
Line 778 ⟶ 1,353:
trash = shuffle(10)
"Shuffled array: "; trash = print_array(10)
quit</
{{out}}
<pre>Original array: 11, 22, 33, 44, 55, 66, 77, 88, 99, 110
Shuffled array: 66, 44, 11, 55, 33, 77, 110, 22, 88, 99</pre>
=={{header|BQN}}==
BQN's arrays are immutable, but variable values can be changed using the `↩` symbol. This program repeatedly changes the array's value using under.
<syntaxhighlight lang="bqn">Knuth ← {
𝕊 arr:
l ← ≠arr
{
arr ↩ ⌽⌾(⟨•rand.Range l, 𝕩⟩⊸⊏)arr
}¨↕l
arr
}
P ← •Show Knuth
P ⟨⟩
P ⟨10⟩
P ⟨10, 20⟩
P ⟨10, 20, 30⟩</syntaxhighlight>
[https://mlochbaum.github.io/BQN/try.html#code=S251dGgg4oaQIHsKICDwnZWKIGFycjoKICBsIOKGkCDiiaBhcnIKICB7CiAgICBhcnIg4oapIOKMveKMvijin6jigKJyYW5kLlJhbmdlIGwsIPCdlanin6niirjiio8pYXJyCiAgfcKo4oaVbAogIGFycgp9ClAg4oaQIOKAolNob3cgS251dGgKClAg4p+o4p+pClAg4p+oMTDin6kKUCDin6gxMCwgMjDin6kKUCDin6gxMCwgMjAsIDMw4p+p Try It!]
=={{header|Brat}}==
<
(a.length - 1).to 1 { i |
random_index = random(0, i)
Line 795 ⟶ 1,391:
}
p shuffle [1 2 3 4 5 6 7]</
=={{header|C}}==
This shuffles any "object"; it imitates <tt>qsort</tt> in the syntax.
<
#include <string.h>
Line 819 ⟶ 1,415:
}
free(temp);
} </
Alternatively, using Durstenfeld's method (swapping selected item and last item in each iteration instead of literally shifting everything), and macro'd function declaration/definition:
<
#include <stdlib.h>
Line 872 ⟶ 1,468:
printf(" %d", x[i]);
return 0;
}</
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">public static void KnuthShuffle<T>(T[] array)
{
System.Random random = new System.Random();
for (int i = 0; i < array.Length; i++)
{
int j = random.Next(i, array.Length); // Don't select from the entire array on subsequent loops
T temp = array[i]; array[i] = array[j]; array[j] = temp;
}
}</syntaxhighlight>
=={{header|C++}}==
'''Compiler:''' [[g++]] (version 4.3.2 20081105 (Red Hat 4.3.2-7))
<
#include <algorithm>
#include <iterator>
Line 882 ⟶ 1,489:
template<typename RandomAccessIterator>
void knuthShuffle(RandomAccessIterator begin, RandomAccessIterator end) {
if(begin == end) {
return;
}
for(unsigned int n = end - begin - 1; n >= 1; --n) {
unsigned int k = rand() % (n + 1);
Line 888 ⟶ 1,498:
}
}
}</
The standard library provides this in the form of <code>std::random_shuffle</code>.
<
#include <vector>
Line 900 ⟶ 1,510:
std::random_shuffle(array, array + 9); // shuffle C-style array
std::random_shuffle(vec.begin(), vec.end()); // shuffle STL container
}</
=={{header|Clojure}}==
<
(reduce (fn [v i] (let [r (rand-int i)]
(assoc v i (v r) r (v i))))
vect (range (dec (count vect)) 1 -1)))</
This works by generating a sequence of end-indices from n-1 to 1, then reducing that sequence (starting with the original vector) through a function that, given a vector and end-index, performs a swap between the end-index and some random index less than the end-index.
=={{header|
<syntaxhighlight lang="clu">knuth_shuffle = proc [T: type] (a: array[T])
lo: int := array[T]$low(a)
hi: int := array[T]$high(a)
for i: int in int$from_to_by(hi, lo+1, -1) do
j: int := lo + random$next(i-lo+1)
temp: T := a[i]
a[i] := a[j]
a[j] := temp
end
end knuth_shuffle
start_up = proc ()
po: stream := stream$primary_output()
d: date := now()
random$seed(d.second + 60*(d.minute + 60*d.hour))
arr: array[int] := array[int]$[1,2,3,4,5,6,7,8,9]
knuth_shuffle[int](arr)
for i: int in array[int]$elements(arr) do
stream$puts(po, int$unparse(i) || " ")
end
end start_up</syntaxhighlight>
{{out}}
<pre>7 9 2 3 4 8 1 6 5</pre>
(Or any other order.)
=={{header|CMake}}==
<
# stores the result in a list.
function(shuffle var)
Line 984 ⟶ 1,578:
endforeach(i)
set("${var}" ${answer} PARENT_SCOPE)
endfunction(shuffle)</
<
message(STATUS "${result}")
# One possible output:
# -- 66;33;22;55;44;11</
=={{header|COBOL}}==
<syntaxhighlight lang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. knuth-shuffle.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 i PIC 9(8).
01 j PIC 9(8).
01 temp PIC 9(8).
LINKAGE SECTION.
78 Table-Len VALUE 10.
01 ttable-area.
03 ttable PIC 9(8) OCCURS Table-Len TIMES.
PROCEDURE DIVISION USING ttable-area.
MOVE FUNCTION RANDOM(FUNCTION CURRENT-DATE (11:6)) TO i
PERFORM VARYING i FROM Table-Len BY -1 UNTIL i = 0
COMPUTE j =
FUNCTION MOD(FUNCTION RANDOM * 10000, Table-Len) + 1
MOVE ttable (i) TO temp
MOVE ttable (j) TO ttable (i)
MOVE temp TO ttable (j)
END-PERFORM
GOBACK
.</syntaxhighlight>
=={{header|CoffeeScript}}==
{{trans|JavaScript}}
<
n = a.length
while n > 1
Line 1,013 ⟶ 1,638:
for key, val of counts
console.log "#{key}: #{val}"</
{{out}}
<pre>
Line 1,026 ⟶ 1,651:
=={{header|Common Lisp}}==
<
(loop for i from (length sequence) downto 2
do (rotatef (elt sequence (random i))
(elt sequence (1- i))))
sequence)</
This operates on arbitrary sequences, but will be inefficient applied to a list as opposed to a vector. Dispatching on type, and using an intermediate vector to hold the contents of list can make both cases more efficient (since the array specific case can use <code>aref</code> rather than <code>elt</code>):
<
(etypecase sequence
(list (nshuffle-list sequence))
Line 1,047 ⟶ 1,672:
do (rotatef (aref array (random i))
(aref array (1- i)))
finally (return array)))</
=={{header|Crystal}}==
<syntaxhighlight lang="crystal">def knuthShuffle(items : Array)
i = items.size-1
while i > 1
j = Random.rand(0..i)
items.swap(i, j)
i -= 1
end
end</syntaxhighlight>
=={{header|D}}==
===Standard Version===
A variant of the Knuth shuffle is in the D standard library Phobos:
<
import std.stdio, std.random;
Line 1,057 ⟶ 1,694:
a.randomShuffle;
a.writeln;
}</
{{out}}
<pre>[8, 9, 3, 1, 7, 5, 4, 6, 2]</pre>
Line 1,063 ⟶ 1,700:
===One Implementation===
This shuffles any collection that supports random access, length and swapping of items:
<
void knuthShuffle(Range)(Range r)
Line 1,076 ⟶ 1,713:
a.knuthShuffle;
a.writeln;
}</
=={{header|Delphi}}==
Line 1,082 ⟶ 1,719:
=={{header|DWScript}}==
<
var
i, j, tmp : Integer;
Line 1,090 ⟶ 1,727:
tmp:=a[i]; a[i]:=a[j]; a[j]:=tmp;
end;
end;</
=={{header|E}}==
<
for bound in (2..(array.size())).descending() {
def i := random.nextInt(bound)
Line 1,101 ⟶ 1,738:
array[i] := t
}
}</
<
# value: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].diverge()
? shuffle(arr, entropy)
? arr
# value: [4, 5, 2, 9, 7, 8, 1, 3, 6, 10].diverge()</
=={{header|EasyLang}}==
<syntaxhighlight>
proc shuffle . a[] .
for i = len a[] downto 2
r = randint i
swap a[r] a[i]
.
.
arr[] = [ 1 2 3 ]
shuffle arr[]
print arr[]
</syntaxhighlight>
=={{header|EchoLisp}}==
<
Remark- The native '''shuffle''' function implementation in EchoLisp has been replaced by this one.
Thx Rosetta Code.
Line 1,140 ⟶ 1,790:
'(adrien 🎸 alexandre 🚂 antoine 🍼 ben 📚 georges 📷 julie 🎥 marine 🐼 nathalie 🍕 ))
→ (antoine 🎥 🚂 marine adrien nathalie 🍼 🍕 ben 🐼 julie 📷 📚 🎸 alexandre georges)
</syntaxhighlight>
=={{header|Egel}}==
<syntaxhighlight lang="egel">
import "prelude.eg"
import "random.ego"
Line 1,161 ⟶ 1,811:
def main = shuffle (fromto 1 9)
</syntaxhighlight>
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
APPLICATION
Line 1,221 ⟶ 1,871:
end
</syntaxhighlight>
{{out}}
<pre>
Line 1,227 ⟶ 1,877:
Shuffeld: 1 5 3 4 7 6 2
</pre>
=={{header|Elena}}==
ELENA
<
import extensions;
Line 1,242 ⟶ 1,891:
var max := self.Length;
for(int i := 0
{
var j := randomGenerator.
self.exchange(i,j)
Line 1,255 ⟶ 1,904:
public program()
{
var a := Array.allocate
console.printLine(a.randomize())
}</
{{out}}
<pre>
</pre>
=={{header|Elixir}}==
{{trans|Erlang}}
<
def shuffle( inputs ) do
n = length( inputs )
Line 1,287 ⟶ 1,936:
Map.update(acc, k, 1, &(&1+1))
end)
|> Enum.each(fn {k,v} -> IO.inspect {k,v} end)</
{{out}}
Line 1,301 ⟶ 1,950:
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module( knuth_shuffle ).
Line 1,316 ⟶ 1,965:
Item = lists:nth( random:uniform(N), Inputs ),
{lists:delete(Item, Inputs), [Item | Acc]}.
</syntaxhighlight>
{{out}}
<pre>
Line 1,324 ⟶ 1,973:
=={{header|ERRE}}==
<
CONST CARDS%=52
Line 1,343 ⟶ 1,992:
PRINT
END PROGRAM
</syntaxhighlight>
=={{header|Euphoria}}==
{{trans|BASIC}}
<
cards = repeat(0,52)
integer card,temp
Line 1,369 ⟶ 2,018:
for i = 1 to 52 do
printf(1,"%d ",cards[i])
end for</
=={{header|F_Sharp|F#}}==
Allows a shuffle of arrays of arbitrary items. Requires 2010 beta of F#. Lazily returns a sequence.
This is the original Fisher-Yates shuffle as described by the link:
<syntaxhighlight lang="fsharp">open System
let FisherYatesShuffle (initialList : array<'a>) = // '
let availableFlags = Array.init initialList.Length (fun i -> (i, true))
// Which items are available and their indices
let rnd = new Random()
let nextItem nLeft =
let nItem = rnd.Next(0, nLeft) // Index out of available items
let index = // Index in original deck
availableFlags // Go through available array
|> Seq.filter (fun (ndx,f) -> f) // and pick out only the available tuples
|> Seq.nth nItem // Get the one at our chosen index
|> fst // and retrieve it's index into the original array
availableFlags.[index] <- (index, false) // Mark that index as unavailable
initialList.[index] // and return the original item
seq {(initialList.Length) .. -1 .. 1} // Going from the length of the list down to 1
|> Seq.map (fun i -> nextItem i) // yield the next item</syntaxhighlight>
Here's the modified Knuth shuffle which shuffles the original array in place
<syntaxhighlight lang="fsharp">let KnuthShuffle (lst : array<'a>) = // '
let Swap i j = // Standard swap
let item = lst.[i]
lst.[i] <- lst.[j]
lst.[j] <- item
let rnd = new Random()
let ln = lst.Length
[0..(ln - 2)] // For all indices except the last
|> Seq.iter (fun i -> Swap i (rnd.Next(i, ln))) // swap th item at the index with a random one following it (or itself)
lst // Return the list shuffled in place</syntaxhighlight>
Example:
<syntaxhighlight lang="fsharp">> KnuthShuffle [| "Darrell"; "Marvin"; "Doug"; "Greg"; "Sam"; "Ken" |];;
val it : string array = [|"Marvin"; "Doug"; "Sam"; "Darrell"; "Ken"; "Greg"|]</syntaxhighlight>
=={{header|Factor}}==
There is a <code>randomize</code> word already in the standard library. Implementation:
<
dup length [ dup 1 > ]
[ [ iota random ] [ 1 - ] bi [ pick exchange ] keep ]
while drop ;</
=={{header|Fantom}}==
<
{
static Void knuthShuffle (List array)
Line 1,400 ⟶ 2,085:
echo (b)
}
}</
=={{header|Forth}}==
<
: shuffle ( deck size -- )
Line 1,417 ⟶ 2,102:
create deck 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,
deck 10 2dup shuffle .array</
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
implicit none
Line 1,453 ⟶ 2,138:
end subroutine Shuffle
end program Knuth_Shuffle</
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
' for boundry checks on array's compile with: fbc -s console -exx
Line 1,531 ⟶ 2,217:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre>Starting array
Line 1,551 ⟶ 2,237:
=={{header|Frink}}==
The built-in method <CODE><I>array</I>.shuffle[]</CODE> implements the Fisher-Yates-Knuth shuffle algorithm:
<
a = [1,2,3]
a.shuffle[]
</syntaxhighlight>
=={{header|FunL}}==
<
res = array( a )
n = a.length()
Line 1,601 ⟶ 2,251:
res(i), res(r) = res(r), res(i)
res.toList()</
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
void local fn KnuthShuffle( mutArr as CFMutableArrayRef )
NSUInteger i, j, count
count = len(mutArr)
for i = count-1 to 1 step -1
j = rnd(i+1)-1
MutableArrayExchangeObjects( mutArr, i, j )
next
end fn
randomize
CFMutableArrayRef mutArr
NSUInteger i
mutArr = fn MutableArrayWithObjects( @0, @1, @2, @3, @4, @5, @6, @7, @8, @9, NULL )
NSLog( @"Before shuffle: %@", fn ArrayComponentsJoinedByString( mutArr, @"" ) )
for i = 1 to 100
fn KnuthShuffle( mutArr )
NSLog( @"%@", fn ArrayComponentsJoinedByString( mutArr, @"" ) )
next
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Before shuffle: 0123456789
1274860395
2715638904
7182035964
1297658403
2916574083
9162507843
1875962034
8721965034
7968402351
9347510862
</pre>
=={{header|Gambas}}==
'''[https://gambas-playground.proko.eu/?gist=58402023fbdc617ce10f6a85db721105 Click this link to run this code]'''
<
Dim iTotal As Integer = 40
Dim iCount, iRand1, iRand2 As Integer
Line 1,630 ⟶ 2,325:
Next
End</
Output:
<pre>
Line 1,638 ⟶ 2,333:
=={{header|GAP}}==
<
ShuffleAlt := function(a)
local i, j, n, t;
Line 1,663 ⟶ 2,358:
# One may also call the built-in random generator on the symmetric group :
Random(SymmetricGroup(10));
(1,8,2,5,9,6)(3,4,10,7)</
=={{header|Go}}==
Line 1,671 ⟶ 2,366:
implementing a Fisher–Yates shuffle.)
<
import (
Line 1,692 ⟶ 2,387:
}
fmt.Println(a)
}</
To shuffle any type:
<
import (
Line 1,741 ⟶ 2,436:
shuffle(a)
fmt.Println(a)
}</
{{out|Example output}} (of either program)
<pre>
Line 1,750 ⟶ 2,445:
=={{header|Groovy}}==
Solution:
<
if (list == null || list.empty) return list
def r = new Random()
Line 1,759 ⟶ 2,454:
}
list
}</
Test:
<
println list
println shuffle(list)
println shuffle(list)
println shuffle(list)</
{{out}}
<pre>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Line 1,773 ⟶ 2,468:
=={{header|Haskell}}==
<
mkRands :: Int -> IO [Int]
Line 1,789 ⟶ 2,484:
knuthShuffle :: [a] -> IO [a]
knuthShuffle xs = (foldr swapElems xs . zip [1 ..]) <$> mkRands (length xs)</
or, as an alternative to making two indexed references into the list with '''(!!)''':
<
import Data.Bool (bool)
Line 1,813 ⟶ 2,508:
main :: IO ()
main = knuthShuffle ['a' .. 'k'] >>= print</
Examples of use of either of the two versions above:
Line 1,822 ⟶ 2,517:
[(0,10),(8,18),(2,12),(3,13),(9,19),(4,14),(7,17),(1,11),(6,16),(5,15)]</pre>
Function for showing intermediate results:
<
knuthShuffleProcess =
(mapM_ print. reverse =<<). ap (fmap. (. zip [1..]). scanr swapElems) (mkRands. length)</
{{out}} Detailed example:
<pre>*Main> knuthShuffleProcess ['a'..'k']
Line 1,839 ⟶ 2,534:
"iebjhkcgfad"</pre>
An imperative implementation using arrays and the <code>ST</code> monad:
<
import Data.STRef
import Control.Monad
Line 1,859 ⟶ 2,554:
where len = length list
newAry :: (Int, Int) -> [a] -> ST s (STArray s Int a)
newAry = newListArray</
=={{header|Icon}} and {{header|Unicon}}==
The <tt>shuffle</tt> method used here can shuffle lists, record fields, and strings:
<
show(shuffle([3,1,4,1,5,9,2,6,3]))
show(shuffle("this is a string"))
Line 1,876 ⟶ 2,571:
every writes(!A," ")
write()
end</
{{out}}
<pre>->ks
Line 1,883 ⟶ 2,578:
-></pre>
Note that the gloriously succinct 'standard' Icon shuffle:
<
every !A :=: ?A
end</
is subtly biased.
=={{header|Inform 6}}==
<
for (i = n - 1: i > 0: i--) {
j = random(i + 1) - 1;
tmp = a->j;
a->j = a->i;
a->i = tmp;
}
];</
=={{header|J}}==
<
The input array is transformed to a rectangular array of indexes. By doing this all kinds of arrays can serve as input (see examples below). The process is imitated by using using a fold, swapping elements in a restricted part of this index-array in each fold step.
<
fold swap transform array <==> f / g y</
Example of a transformed input:
<
0 0 0 0 0 0
1 1 0 0 0 0
Line 1,914 ⟶ 2,608:
4 3 0 0 0 0
5 0 0 0 0 0
0 1 2 3 4 5</
The last row is the index-array that has to be shuffled. The other rows have valid indexes in the first two columns. The second column has a randomized value <= value first column.
The index-swapping is done by the part:
<
Finally, the shuffled indexes select elements from the original array.
<syntaxhighlight lang
Alternatively, instead of creating a rectangular array, the swapping indices and the original data can be individually boxed.
Line 1,926 ⟶ 2,620:
With this approach, the data structure with the swapping indices and the original data could look like this:
<
+---+-+---+---+-+-----+
|4 2|3|2 1|1 0|0|abcde|
+---+-+---+---+-+-----+</
Note that we have the original data here, instead of indices to select all of its items. Note also that we have only a single value in a box where an item is being "swapped" with itself (this is required by J's cycle operation (<code>C.</code>)).
The resulting definition looks like this:
<
Note that here we did not wind up with a list of indices which we used to permute the original data set. That data set is permuted directly. However, it is in a box and we do have to remove it from that box.
Permuting the data directly, instead of permuting indices, has performance implications when the items being swapped are large, but see the note at the end of this entry for J for how you would do this operation in a "real" J program.
Examples:<
5 6 7 8 9 10 11 12 13</
<
13 10 7 5 11 9 8 6 12</
<
1 1 1
1 0 0
Line 1,953 ⟶ 2,647:
11 2 3
0 11 2</
<
11 2 3
0 11 2
Line 1,965 ⟶ 2,659:
1 2 3
2 3 4</
<
+--+---+----+---+
|aA|bbB|cC%$|dD@|
+--+---+----+---+</
<
+--+----+---+---+
|aA|cC%$|dD@|bbB|
+--+----+---+---+</
In J the shuffling of an arbitrary array can easily be implemented by the phrase
( ref http://www.jsoftware.com/jwiki/JPhrases/RandomNumbers ):
<syntaxhighlight lang
Applied on the former examples:
<
8 7 13 6 10 11 5 9 12
Line 1,997 ⟶ 2,691:
+----+---+--+---+
|cC%$|bbB|aA|dD@|
+----+---+--+---+</
=={{header|Java}}==
<
public static final Random gen = new Random();
Line 2,023 ⟶ 2,717:
array[k] = temp;
}
}</
=={{header|JavaScript}}==
Line 2,029 ⟶ 2,723:
===ES5===
<
var rand, temp, i;
for (i = arr.length - 1; i > 0; i -= 1) {
rand = Math.floor((i + 1) * Math.random());//get random between zero and i (inclusive)
temp = arr[rand];
arr[rand] = arr[i]; //swap i (last element) with random element.
arr[i] = temp;
}
Line 2,053 ⟶ 2,747:
for (var key in res) {
print(key + "\t" + res[key]);
}</
Results in:
<pre>1,2,3 16619
Line 2,061 ⟶ 2,755:
3,1,2 16460
3,2,1 16596</pre>
===ES6===
====Mutating in-place swap====
<
// knuthShuffle :: [a] -> [a]
Line 2,112 ⟶ 2,805:
return test();
})();
</syntaxhighlight>
{{Out}}
e.g.
<
"lambda", "eta", "zeta", "beta", "mu", "alpha"]</
====Non-mutating swap====
<
// knuthShuffle :: [a] -> [a]
Line 2,180 ⟶ 2,873:
// MAIN ---
return test();
})();</
{{Out}}
e.g.
<
"kappa", "alpha", "gamma", "lambda", "zeta", "iota"]</
=={{header|Joy}}==
<
(* Take the size of the array (without destroying it) *)
dup dup size
(* Generate a list of as many random numbers *)
[rand] [rem] enconcat map
(* Zip the two lists *)
swap zip
(* Sort according to the new index number *)
[small] [] [uncons unswonsd [first >] split [swons] dip2]
[enconcat] binrec
(* Delete the new index number *)
[second] map.</
Using knuth-shuffle (file shuffle.joy):
<
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
knuth-shuffle.</
Command line:
: <tt>joy shuffle.joy</tt>
Line 2,217 ⟶ 2,905:
[12 6 8 4 14 18 7 15 1 0 11 13 5 10 16 2 19 17 9 20 3]
</pre>
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
Neither the C nor the Go implementations of jq has a built-in PRNG, but both are designed with the Unix toolset philosophy in mind,
so in this entry we will use an external source of randomness rather than
one of the PRNGs defined in jq as at RC.
Specifically, we will use /dev/urandom like so:
< /dev/urandom tr -cd '0-9' | fold -w 1 | jq -RMnrc -f program.jq
where program.jq is the following program:
<syntaxhighlight lang="jq">
# 52-card deck:
def deck:
[range(127137; 127148), range(127149; 127151), # Spades
range(127153; 127164), range(127165; 127167), # Hearts
range(127169; 127180), range(127181; 127183), # Diamonds
range(127185; 127196), range(127197; 127199)] # Clubs
;
# For splitting a deck into hands :-)
def nwise($n):
def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
n;
# Output: a prn in range(0;$n) where $n is ., and $n > 0
def prn:
if . == 1 then 0
else . as $n
| (($n-1)|tostring|length) 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;
def task:
[],
[10,20],
[10,20,30]
| knuthShuffle;
task,
(deck|knuthShuffle | nwise(13) | implode)
</syntaxhighlight>
{{out}}
<pre>
[]
[10,20]
[20,30,10]
</pre>
<p style="font-size:36px">
🂶🃚🃈🃘🃊🂥🃉🂽🂣🂸🃂🂺🃗<br>
🂵🃁🃇🂮🂹🃝🃆🂱🂻🂩🃋🂭🃖<br>
🂢🃛🃕🃃🂾🃙🃞🂨🂪🂲🂷🃍🂫<br>
🂦🃒🃔🂳🂡🃓🃄🂴🃅🃎🃑🂤🂧
</p>
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
for i in length(v):-1:2
j = rand(r, 1:i)
Line 2,231 ⟶ 2,990:
v = collect(1:20)
println("# v = $v\n -> ", knuthshuffle!(v))</
{{out}}
Line 2,238 ⟶ 2,997:
=={{header|Kotlin}}==
<
internal val gen = java.util.Random()
}
Line 2,268 ⟶ 3,027:
require(s.toSortedSet() == ia.toSet())
}
}</
{{out}}
<pre>xdhsvtnumjgbywiqoapcelkrfz
Line 2,296 ⟶ 3,055:
[[File:Knuth_shuffle_diagram.png|200px]]
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
{def shuffle
{def shuffle.in
{lambda {:a}
{S.map {{lambda {:a :i}
{A.swap :i
{floor {* {random} {+ :i 1}}} // j = random integer from 0 to i+1
:a}} :a}
{S.serie {- {A.length :a} 1} 0 -1}}}} // from length-1 to 0
{lambda {:a}
{let { {:b {A.duplicate :a}} } // optionnaly prevents modifying the original array
{S.replace \s by in {shuffle.in :b} // trim extra spaces
:b}}}} // return the new array
-> shuffle
{def A.swap // should probably be promoted as a primitive
{lambda {:i :j :a}
{let { {:i :i}
{:gja {A.get :j :a}}
{:b {A.set! :j {A.get :i :a} :a}}
} {let { {_ {A.set! :i :gja :b} }}}}}} // side effect without any return value
-> A.swap
{def B {A.new a b c d e f g h i j k l m n o p q r s t u v w x y z}}
-> B
{shuffle {B}}
-> [z,t,q,w,c,n,a,u,r,y,i,s,f,d,g,m,h,x,b,e,k,p,l,o,j,v]
</syntaxhighlight>
=={{header|Lasso}}==
<
fail_if(
#p1 < 1 or #p2 < 1 or
Line 2,317 ⟶ 3,108:
}
(1 to 10)->asStaticArray->knuthShuffle&asString</
{{out}}
<pre>staticarray(9, 5, 6, 1, 10, 8, 3, 4, 2, 7)</pre>
=={{header|Liberty BASIC}}==
<
UpperBound = 9
Dim array(UpperBound)
Line 2,344 ⟶ 3,134:
For i = 0 To UpperBound
Print array(i)
Next i</
=={{header|Logo}}==
<
localmake "t item :i :a
setitem :i :a item :j :a
Line 2,358 ⟶ 3,148:
make "a {1 2 3 4 5 6 7 8 9 10}
shuffle :a
show :a</
Lhogho does not have a setitem, and also does things more 'function'ally.
<
local "res
make "res []
Line 2,396 ⟶ 3,186:
make "a ( list 1 2 3 4 5 6 7 8 9 10 )
make "a shuffle :a
show :a</
=={{header|Lua}}==
<
for n = #t, 1, -1 do
local k = math.random(n)
Line 2,411 ⟶ 3,201:
a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
table.shuffle(a)
for i,v in ipairs(a) do print(i,v) end</
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Dim Base 0, A(3)
For k=1 to 6 {
Line 2,426 ⟶ 3,215:
}
</syntaxhighlight>
=={{header|M4}}==
<
define(`randSeed',141592653)
define(`rand_t',`eval(randSeed^(randSeed>>13))')
Line 2,455 ⟶ 3,244:
show(`b')
shuffle(`b')
show(`b')</
{{out}}
<pre>
Line 2,467 ⟶ 3,256:
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Usage of built-in function:
<
Custom function:
<
Module[{indices = {}, allindices = Range[Length[input]]},
Do[
Line 2,480 ⟶ 3,269:
];
input[[indices]]
]</
Example:
<
=={{header|MATLAB}}==
Because this shuffle is done using rounds of operations on subsets of decreasing size, this is not an algorithm that can be vectorized using built-in MATLAB functions. So, we have to go old-school, no fancy MATLAB trickery.
<
for i = (numel(list):-1:2)
Line 2,495 ⟶ 3,284:
list([j i]) = list([i j]);
end
end</
There is an alternate way to do this that is not a true Knuth Shuffle, but operates with the same spirit.
This alternate version produces the same output, saves some space,
and can be implemented in-line without the need to encapsulate it
in a function call like the Knuth Shuffle.
<
list = list( randperm(numel(list)) );
end</
=={{header|Maxima}}==
<
random_permutation([a, b, c]);</
=={{header|Modula-3}}==
<
IMPORT IO, Fmt, Random;
Line 2,539 ⟶ 3,328:
END;
IO.Put("\n");
END Shuffle.</
{{out}}
<pre>
Line 2,549 ⟶ 3,338:
=={{header|MUMPS}}==
<
Set list="",n=0
Set ii="" For Set ii=$Order(items(ii)) Quit:ii="" Do
Line 2,632 ⟶ 3,421:
Queen of Spades
King of Diamonds
5 of Clubs</
=={{header|Nemerle}}==
<
{
def rnd = Random();
Line 2,642 ⟶ 3,431:
arr[i] <-> arr[(rnd.Next(i, arr.Length))];
arr
}</
=={{header|NetRexx}}==
===version 1===
<
options replace format comments java crossref savelog symbols nobinary
Line 2,694 ⟶ 3,483:
say
return</
{{out}}
<pre>
Line 2,709 ⟶ 3,498:
===version 2===
<
* 08.01.2014 Walter Pachl modified to show state development a la Rexx
*--------------------------------------------------------------------*/
Line 2,742 ⟶ 3,531:
method showHand(deck = ArrayList,tag=REXX) public static binary
say tag ArrayList(deck.subList(0,deck.size)).toString
return</
{{out}}
<pre>In [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Line 2,757 ⟶ 3,546:
=={{header|Nim}}==
Note that the function "shuffle" exists in the standard module "random" and that it uses the Knuth shuffle.
<syntaxhighlight lang="nim">import random
randomize()
proc shuffle[T](x: var
for i in countdown(x.high,
let j =
swap(x[i], x[j])
var x =
shuffle(x)
echo x</
=={{header|Objective-C}}==
<
@interface NSMutableArray (KnuthShuffle)
Line 2,791 ⟶ 3,581:
}
return 0;
}</
{{out}}
<pre>
Line 2,809 ⟶ 3,599:
=={{header|OCaml}}==
<
for n = Array.length arr - 1 downto 1 do
let k = Random.int (n + 1) in
Line 2,815 ⟶ 3,605:
arr.(n) <- arr.(k);
arr.(k) <- temp
done</
=={{header|Oforth}}==
Line 2,822 ⟶ 3,612:
Returns a new list
<
| s i l |
self asListBuffer ->l
self size dup ->s 1- loop: i [ s i - rand i + i l swapValues ]
l dup freeze ; </
=={{header|Ol}}==
Line 2,833 ⟶ 3,623:
Ol is functional language, so we should make a copy of shuffling tuple and return this shuffled copy.
<
(define (shuffle tp)
(let ((items (vm:cast tp (type tp)))) ; make a copy
Line 2,849 ⟶ 3,639:
(tuple->list
(shuffle (list->tuple (iota (length tp)))))))
</syntaxhighlight>
Testing:
<
(define items (tuple 1 2 3 4 5 6 7 8 9))
(print "tuple before: " items)
Line 2,860 ⟶ 3,650:
(print "list before: " items)
(print "list after: " (list-shuffle items))
</syntaxhighlight>
Output:
<pre>
Line 2,868 ⟶ 3,658:
list after: (8 2 4 9 5 3 6 1 7)
</pre>
=={{header|Oz}}==
<
proc {Shuffle Arr}
Low = {Array.low Arr}
Line 2,889 ⟶ 3,678:
{Show {Array.toRecord unit X}}
{Shuffle X}
{Show {Array.toRecord unit X}}</
=={{header|PARI/GP}}==
<
forstep(n=#v,2,-1,
my(i=random(n)+1,t=v[i]);
Line 2,901 ⟶ 3,690:
};
FY(vector(52,i,i))</
=={{header|Pascal}}==
<
const
Line 2,955 ⟶ 3,744:
DisplayList(a);
end;
end.</
{{out}}
<pre> -5 -4 -3 -2 -1 0 1 2 3 4 5
Line 2,966 ⟶ 3,755:
=={{header|Perl}}==
<
my @a = @_;
foreach my $n (1 .. $#a) {
Line 2,973 ⟶ 3,762:
}
return @a;
}</
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cards</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">52</span><span style="color: #0000FF;">)</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;">"Before: "</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">cards</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">52</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<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;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">cards</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">],</span><span style="color: #000000;">cards</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">cards</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">cards</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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;">"After: "</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">cards</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;">"Sorted: "</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">?</span><span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cards</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre style="font-size: 12px">
Line 3,004 ⟶ 3,783:
=={{header|PHP}}==
<
function yates_shuffle($arr){
$shuffled = Array();
Line 3,021 ⟶ 3,800:
list($arr[$i], $arr[$rnd]) = array($arr[$rnd], $arr[$i]);
}
}</
=={{header|Picat}}==
<syntaxhighlight lang="picat">go =>
_ = random2(),
L = 1..10,
println(l_before=L),
knuth_shuffle(L),
println('l_after '=L),
nl.
knuth_shuffle(L) =>
foreach(I in L.len..-1..1)
J = random(1,I),
Tmp = L[I],
L[I] := L[J],
L[J] := Tmp
end.</syntaxhighlight>
{{out}}
<pre>l_before = [1,2,3,4,5,6,7,8,9,10]
l_after = [2,9,6,7,10,3,5,4,8,1]</pre>
=={{header|PicoLisp}}==
<
(de knuth (Lst)
Line 3,034 ⟶ 3,834:
(println 'before L)
(knuth L)
(println 'after L) )</
{{out}}
<pre>
Line 3,043 ⟶ 3,843:
=={{header|PL/I}}==
===version 1===
<
declare (i, j, temp) fixed binary;
do i = lbound(T,1) to hbound(T,1);
j = min(random() * 12, 11);
temp = T(j); T(j) = T(i); T(i) = temp;
end;</
===version 2===
<
/*--------------------------------------------------------------------
* 07.01.2014 Walter Pachl translated from REXX version 2
Line 3,073 ⟶ 3,873:
Put Edit(txt,(t(k) do k=1 To n))(Skip,a(7),10(f(3)));
End;
end;</
{{out}}
<pre>In 1 2 3 4 5 6 7 8 9 10
Line 3,089 ⟶ 3,889:
=={{header|PowerShell}}==
{{works with|PowerShell|3}}
<
Get-Random $A -Count $A.Count</
{{works with|PowerShell|2}} <!-- Get-Random didn't exist in PowerShell 1 -->
<
$c = $a.Clone() # make copy to avoid clobbering $a
1..($c.Length - 1) | ForEach-Object {
Line 3,100 ⟶ 3,900:
}
$c[-1] # last value
}</
This yields the values one by one instead of returning the array as a whole, so the rest of the pipeline can work on the values while shuffling is still in progress.
=={{header|PureBasic}}==
<
Procedure KnuthShuffle(Array a(1))
Line 3,135 ⟶ 3,935:
KnuthShuffle(a())
Debug "shuffled: " + ArrayToString(a())</
{{out}}
<pre>shuffled: 1,8,6,0,5,9,2,4,7,3</pre>
Line 3,142 ⟶ 3,942:
Python's standard library function <code>[http://docs.python.org/library/random.html#random.shuffle random.shuffle]</code> uses this algorithm and so should normally be used.
The function below is very similar:
<
def knuth_shuffle(x):
Line 3,151 ⟶ 3,951:
x = list(range(10))
knuth_shuffle(x)
print("shuffled:", x)</
{{out}}
<pre>
shuffled: [5, 1, 6, 0, 8, 4, 2, 3, 9, 7]
</pre>
We could also write our own Knuth shuffle function as a fold, with a non-mutating swap function:
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Knuth shuffle as a fold'''
from functools import reduce
from random import randint
# knuthShuffle :: [a] -> IO [a]
def knuthShuffle(xs):
'''A pseudo-random shuffle of the elements in xs.'''
return reduce(
swapped,
enumerate(randoms(len(xs))), xs
)
# swapped :: (Int, Int) -> [a] -> [a]
def swapped(xs, ij):
'''New list in which the elements at indices
i and j of xs are swapped.
'''
def go(a, b):
if a != b:
m, n = (a, b) if b > a else (b, a)
l, ht = splitAt(m)(xs)
ys, zs = splitAt((n - m) - 1)(ht[1:])
return l + [zs[0]] + ys + [ht[0]] + zs[1:]
else:
return xs
i, j = ij
z = len(xs) - 1
return xs if i > z or j > z else go(i, j)
# randoms :: Int -> IO [Int]
def randoms(n):
'''Pseudo-random list of n - 1 indices.
'''
return list(map(randomRInt(0)(n - 1), range(1, n)))
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Repeated Knuth shuffles of ['a' .. 'k']'''
print(
fTable(main.__doc__ + ':\n')(str)(lambda x: ''.join(x))(
lambda _: knuthShuffle(list('abcdefghijk'))
)(range(1, 11))
)
# GENERIC -------------------------------------------------
# randomRInt :: Int -> Int -> IO () -> Int
def randomRInt(m):
'''The return value of randomRInt is itself
a function. The returned function, whenever
called, yields a a new pseudo-random integer
in the range [m..n].
'''
return lambda n: lambda _: randint(m, n)
# splitAt :: Int -> [a] -> ([a], [a])
def splitAt(n):
'''A tuple pairing the prefix of length n
with the rest of xs.
'''
return lambda xs: (xs[0:n], xs[n:])
# FORMATTING -----------------------------------------------------------
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''
def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
# MAIN ---
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>Repeated Knuth shuffles of ['a' .. 'k']:
1 -> kdafbhigejc
2 -> jhdkgeicabf
3 -> aciebghdfkj
4 -> fjahegibckd
5 -> cabejfidkgh
6 -> gbecahfkijd
7 -> jegchkdifba
8 -> fcjkghiadeb
9 -> ihfebdajgkc
10 -> hjkigbadcfe</pre>
=={{Header|Quackery}}==
The word ''shuffle'' is predefined in Quackery (and shown below) - it shuffles a nest (an immutable dynamic array) by removing random items from the nest (i.e. creating a new array with that item removed) and appending them to an (initially empty) nest (i.e. creating a new array with that item appended). It fits the criteria for this task with the relaxations noted at the end of the task description.
The word ''knuffle'' is ''probably'' an entirely in-place shuffle, ''if'' the dynamic memory allocation routines for a particular implementation of Quackery allow in-place modification of a dynamic array when there is only a single pointer to the array. (After the first invocation of ''poke'' inside ''[exch]'' there will definitely only be a single pointer to the array.)
<syntaxhighlight lang="quackery"> [ [] swap dup size times
[ dup size random pluck
nested rot join swap ]
drop ] is shuffle ( [ --> [ )
[ temp put
2dup swap
temp share swap peek
temp share rot peek
dip
[ swap
temp take
swap poke
temp put ]
swap
temp take
swap poke ] is [exch] ( n n [ --> [ )
[ dup size 1 - times
[ i 1+ dup 1+ random
rot [exch] ] ] is knuffle ( [ --> [ )</syntaxhighlight>
{{out}}
Testing in the Quackery shell (REPL).
<pre>/O> ' [ 10 11 12 13 14 15 16 17 18 19 ]
... 10 times [ knuffle dup echo cr ]
...
[ 14 19 11 13 18 17 10 16 12 15 ]
[ 10 15 18 17 13 14 12 16 11 19 ]
[ 19 11 10 14 15 16 12 18 17 13 ]
[ 14 13 19 15 10 16 11 17 18 12 ]
[ 18 13 11 15 17 16 12 10 14 19 ]
[ 18 17 10 13 12 19 15 16 14 11 ]
[ 10 19 17 12 13 14 15 16 18 11 ]
[ 10 16 17 18 13 11 15 19 12 14 ]
[ 18 19 17 11 10 14 16 12 13 15 ]
[ 19 11 10 14 16 12 17 18 15 13 ]
Stack: [ 10 15 13 14 12 19 16 11 17 18 ]
/O> 10 times [ shuffle dup echo cr ]
...
[ 10 13 11 14 18 15 12 17 16 19 ]
[ 12 19 16 17 10 13 14 11 18 15 ]
[ 11 14 12 17 15 19 13 16 18 10 ]
[ 17 15 14 18 16 19 11 10 13 12 ]
[ 14 15 18 13 10 16 17 12 19 11 ]
[ 12 14 11 16 15 10 19 18 17 13 ]
[ 14 12 15 18 16 19 11 10 13 17 ]
[ 18 19 15 16 14 12 13 11 17 10 ]
[ 14 18 19 11 16 12 13 15 17 10 ]
[ 17 19 11 18 14 10 12 13 16 15 ]
Stack: [ 17 19 11 18 14 10 12 13 16 15 ]
</pre>
Line 3,160 ⟶ 4,135:
See also, the built-in function 'sample'.
===Original Fisher-Yates version===
<
{
pool <- seq_len(n)
Line 3,172 ⟶ 4,147:
}
a
}</
===Knuth variation
<
{
a <- seq_len(n)
Line 3,194 ⟶ 4,169:
fisheryatesshuffle(6) # e.g. 1 3 6 2 4 5
x <- c("foo", "bar", "baz", "quux")
x[fisheryatesknuthshuffle(4)] # e.g. "bar" "baz" "quux" "foo"</
===Short version===
After accounting for R being 1-indexed rather than 0-indexed, it's not hard to implement the pseudo-code given in the task almost exactly:
<syntaxhighlight lang="rsplus">knuth <- function(vec)
{
last <- length(vec)
if(last >= 2)
{
for(i in last:2)
{
j <- sample(seq_len(i), size = 1)
vec[c(i, j)] <- vec[c(j, i)]
}
}
vec
}
#Demonstration:
knuth(integer(0))
knuth(c(10))
replicate(10, knuth(c(10, 20)))
replicate(10, knuth(c(10, 20, 30)))
knuth(c("Also", "works", "for", "strings"))</syntaxhighlight>
{{Out}}
<pre>> knuth(integer(0))
integer(0)
> knuth(c(10))
[1] 10
> replicate(10, knuth(c(10, 20)))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 20 20 10 10 20 10 20 10 20 10
[2,] 10 10 20 20 10 20 10 20 10 20
> replicate(10, knuth(c(10, 20, 30)))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 30 10 20 20 30 30 10 30 10 10
[2,] 10 20 30 10 10 10 20 20 20 20
[3,] 20 30 10 30 20 20 30 10 30 30
> knuth(c("Also", "works", "for", "strings"))
[1] "strings" "Also" "for" "works"</pre>
=={{header|Racket}}==
<
(define (swap! vec i j)
Line 3,209 ⟶ 4,221:
(vector->list (knuth-shuffle (list->vector x)))
(begin (for ([i (in-range (sub1 (vector-length x)) 0 -1)])
(define r (random (+ i 1)))
(swap! x i r))
x)))
(knuth-shuffle '(1 2 3 4))</
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|#21 "Seattle"}}
<syntaxhighlight lang="raku" line>sub shuffle (@a is copy) {
for 1 ..^ @a -> $n {
my $k = (0 .. $n).pick;
$k == $n or @a[$k, $n] = @a[$n, $k];
}
return @a;
}</syntaxhighlight>
The shuffle is also built into the pick method on lists when you pass it a "whatever" for the number to pick:
<syntaxhighlight lang="raku" line>my @deck = @cards.pick(*);</syntaxhighlight>
=={{header|REBOL}}==
<
Title: "Fisher-Yates"
Purpose: {Fisher-Yates shuffling algorithm}
Line 3,233 ⟶ 4,258:
]
b
]</
=={{header|REXX}}==
===version 0, card pips===
<
rank= 'A 2 3 4 5 6 7 8 9 10 J Q K' /*pips of the various playing cards. */
suit= '♣♠♦♥' /*suit " " " " " */
Line 3,259 ⟶ 4,284:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: _=; do m=1 for cards; _=_ @.m; end /*m*/; say _; return</
'''output'''
<pre>
Line 3,271 ⟶ 4,296:
===version 1, card names===
This version handles items with (leading/trailing/embedded) blanks in them, so '''parse''' isn't an option for shuffling.
<
rank = 'ace deuce trey 4 5 6 7 8 9 10 jack queen king' /*use pip names for cards*/
suit = 'club spade diamond heart' /* " suit " " " */
Line 3,297 ⟶ 4,322:
say 'card' right(m, 2) '───►' @.m /*display a particular card from deck. */
end /*m*/
return</
'''output'''
<pre style="height:50ex">
Line 3,420 ⟶ 4,445:
===version 2===
<
* 05.01.2014 Walter Pachl
* borrow one improvement from version 1
Line 3,442 ⟶ 4,467:
Do k=1 To n; ol=ol right(a.k,2); End
Say ol
Return</
{{out}}
<pre>In 1 2 3 4 5 6 7 8 9 10
Line 3,457 ⟶ 4,482:
=={{header|Ring}}==
<
# Project : Knuth shuffle
Line 3,486 ⟶ 4,511:
see svect
see "]" + nl
</syntaxhighlight>
<pre>
[15 1 51 20 45 29 43 8 13 3 41 35 11 7 37 9 38 17 32 48 40 25 44 18 14 50 42 34 2 21 12 4 26 19 23 24 28 46 36 10 5 16 6 49 22 33 39 47 31 52 30 27]
</pre>
=={{header|RPL}}==
Indexes of RPL lists and arrays start at 1.
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪
DUP SIZE 2 '''FOR''' j
j RAND * CEIL
GET LAST OVER j GET PUT j ROT PUT
-1 '''STEP'''
≫ '<span style="color:blue">KNUTH</span>' STO
|
<span style="color:blue">KNUTH</span> ''( {items} ➝ {items} )'' <span style="color:grey">// works also with [items]</span>
for j from last downto 2 do:
let k = random integer in range 1 ≤ k ≤ j
swap items[j] with items[k]
|}
=={{header|Ruby}}==
{{trans|Tcl}}
<
def knuth_shuffle!
j = length
Line 3,513 ⟶ 4,561:
end
r.keys.sort.each {|a| puts "#{a.inspect} => #{r[a]}"}</
results in
<pre>[1, 2, 3] => 16572
Line 3,521 ⟶ 4,569:
[3, 1, 2] => 16838
[3, 2, 1] => 16633</pre>
'''More
<
def knuth_shuffle!
(length - 1).downto(1) do |i|
Line 3,530 ⟶ 4,578:
self
end
end</
=={{header|Run BASIC}}==
<
for i = 1 to 52 ' make deck
cards(i) = i
Line 3,553 ⟶ 4,600:
if i mod 18 = 0 then print
next
print</
=={{header|Rust}}==
{{libheader|rand}}
<
extern crate rand;
Line 3,577 ⟶ 4,624:
knuth_shuffle(&mut v);
println!("after: {:?}", v);
}</
=={{header|Scala}}==
<
for (i <- 1 until a.size reverse) {
val j = util.Random nextInt (i + 1)
Line 3,588 ⟶ 4,635:
}
a
}</
=={{header|Scheme}}==
A functional version, using lists (inefficient), somewhat unusual in reversing the entire initial sublist on each pass instead of just swapping:
<
(import (rnrs base (6))
(srfi :27 random-bits))
Line 3,609 ⟶ 4,656:
(let
((li-prime (semireverse li (random-integer (length li)))))
(cons (car li-prime) (shuffle (cdr li-prime))))))</
A mutable version, using vectors (efficient):
<
(import (rnrs base (6))
(srfi :27 random-bits))
Line 3,633 ⟶ 4,680:
((j (random-integer i)))
(vector-swap! vec (- i 1) j)))
(countdown (vector-length vec))))</
=={{header|Scratch}}==
Line 3,639 ⟶ 4,686:
=={{header|Seed7}}==
<
const type: intArray is array integer;
Line 3,670 ⟶ 4,717:
end for;
writeln;
end func;</
{{out}}
Line 3,676 ⟶ 4,723:
7 5 6 8 3 10 9 4 2 1
</pre>
=={{header|SenseTalk}}==
<syntaxhighlight lang="sensetalk">set list to 1..9 -- a range, will become a list as needed
set last to the number of items in list
repeat with i = last down to 2 -- in SenseTalk, the first index in a list is 1
set j = random (1,i-1)
set [item i of list, item j of list] to [item j of list, item i of list] -- swap items
end repeat
put list</syntaxhighlight>
{{out}}
<pre>
[8,9,7,3,4,5,1,2,6]
</pre>
=={{header|SETL}}==
<syntaxhighlight lang="setl">program knuth_shuffle;
setrandom(0);
array := [1..10];
print("Before shuffling:", array);
shuffle(array);
print("After shuffling: ", array);
proc shuffle(rw tup);
loop for i in [1..#tup-1] do
j := random [i+1..#tup];
[tup(i), tup(j)] := [tup(j), tup(i)];
end loop;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>Before shuffling: [1 2 3 4 5 6 7 8 9 10]
After shuffling: [7 8 1 10 2 5 6 9 4 3]</pre>
=={{header|Sidef}}==
<
for i (a.len ^.. 1) {
var j = i.irand
Line 3,686 ⟶ 4,768:
}
say knuth_shuffle(@(1..10))</
{{out}}
<pre>
Line 3,694 ⟶ 4,776:
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<
implemented (GNU Smalltalk version 3.0.4); so here it is an implementation"
SequenceableCollection extend [
Line 3,715 ⟶ 4,797:
]
]
].</
Testing
<
|c|
c := OrderedCollection new.
c addAll: #( 1 2 3 4 5 6 7 8 9 ).
Shuffler Knuth: c.
c display.</
=={{header|SNOBOL4}}==
<
-include 'Random.sno'
Line 3,754 ⟶ 4,836:
shuffle(a)
output = a2s(a)
end</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 ->
2 10 4 9 1 5 6 8 7 3</pre>
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "shuffle" );
pragma annotate( description, "Implement the Knuth shuffle (aka the" );
pragma annotate( description, "Fisher-Yates-Durstenfeld shuffle)" );
pragma annotate( description, "for an integer array (or, if possible, an array of any" );
pragma annotate( description, "type). The Knuth shuffle is used to create a random" );
pragma annotate( description, "permutation of an array." );
pragma annotate( description, "Note: spar has a built-in arrays.shuffle() function that does this." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Knuth_shuffle" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure shuffle is
subtype array_element_type is string;
type magic_items is array(1..3) of array_element_type;
a : magic_items := ( "bell", "book", "candle" );
t : array_element_type;
k : integer;
begin
for i in reverse arrays.first( a ) .. arrays.last( a )-1 loop
k := integer( numerics.rnd( i+1 ) ) - 1 + arrays.first(a);
t := a(i);
a(i) := a(k);
a(k) := t;
end loop;
for i in arrays.first( a ) .. arrays.last( a ) loop
? a(i);
end loop;
end shuffle;</syntaxhighlight>
{{out}}
<pre>
$ spar shuffle
bell
candle
book
$ spar shuffle
candle
bell
book</pre>
=={{header|Stata}}==
<
function shuffle(a) {
n = length(a)
Line 3,775 ⟶ 4,908:
shuffle(1..10)
end</
'''Output'''
Line 3,785 ⟶ 4,918:
=={{header|Swift}}==
Version that works in Swift 5.x and probably above. This version works for any mutable bidirectional collection although O(n) time complexity can only be guaranteed for a RandomAccessCollection where the index meets the Apple requirements for O(1) access to elements.
Also has the advantage that it implemented the algorithm as written at the top of this page i.e. it counts down from the end and picks the random element from the part of the array that has not yet been traversed.
<syntaxhighlight lang="swift">extension BidirectionalCollection where Self: MutableCollection
{
mutating func shuffleInPlace()
{
var index = self.index(before: self.endIndex)
while index != self.startIndex
{
// Note the use of ... below. This makes the current element eligible for being selected
let randomInt = Int.random(in: 0 ... self.distance(from: startIndex, to: index))
let randomIndex = self.index(startIndex, offsetBy: randomInt)
self.swapAt(index, randomIndex)
index = self.index(before: index)
}
}
}
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a.shuffleInPlace()
print(a)
</syntaxhighlight>
{{out}}
<pre>[1, 5, 2, 7, 6, 0, 9, 8, 4, 3]</pre>
'''Simple version (any Swift version):''' Extend Array with shuffle methods; using arc4random_uniform from C stdlib:
<
extension Array {
Line 3,807 ⟶ 4,967:
print([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].shuffle())
// Swift 1.x:
//println([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].shuffle())</
{{out}}
Line 3,814 ⟶ 4,974:
'''Generic version (any Swift version):''' While the above code is generic in that it works with arrays of any element type, we can use generic global functions to define shuffling for any mutable collection with random-access index type which is far more generic than the above code:
<
func shuffleInPlace<T: MutableCollectionType where T.Index: RandomAccessIndexType>(inout collection: T) {
Line 3,844 ⟶ 5,004:
print(shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
// Swift 1.x:
//println(shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))</
{{out}}
Line 3,851 ⟶ 5,011:
{{works with|Swift | 2.0 }} While the above solutions work with Swift 2.0 as they are, we can use Swift 2.0's Protocol Oriented Programming features to add shuffling methods to any mutable collection that has a random-access index:
<
// Define a protocol for shuffling:
Line 3,900 ⟶ 5,060:
{ /* Implementation provided by Shufflable protocol extension */ }
print([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].shuffle())</
{{out}}
Line 3,906 ⟶ 5,066:
=={{header|Tcl}}==
<
set j [llength $lst]
for {set i 0} {$j > 1} {incr i;incr j -1} {
Line 3,922 ⟶ 5,082:
5 2 1 4 3
% knuth_shuffle {tom dick harry peter paul mary}
tom paul mary harry peter dick</
As a test of skewing (an indicator of a poor implementation) this code was used:
<
foreach val [knuth_shuffle {1 2 3 4 5}] pos {pos0 pos1 pos2 pos3 pos4} {
incr tots($pos) $val
Line 3,934 ⟶ 5,094:
tots(pos2) = 299701
tots(pos3) = 299830
tots(pos4) = 300240</
=={{header|TI-83 BASIC}}==
Line 3,953 ⟶ 5,113:
:DelVar D
:Return
=={{header|Transd}}==
<syntaxhighlight lang="Scheme">#lang transd
MainModule: {
// Define an abstract type Vec to make the shuffling
// function polymorphic
Vec: typedef(Lambda<:Data Bool>(λ d :Data()
(starts-with (_META_type d) "Vector<"))),
kshuffle: (λ v Vec() locals: rnd 0
(for n in Range( (- (size v) 1) 0) do
(= rnd (randr (to-Int n)))
(with tmp (cp (get v n))
(set-el v n (get v rnd))
(set-el v rnd tmp))
)
(lout v)
),
_start: (λ
(with v [10,20,30,40,50,60,70,80,90,100]
(lout "Original:\n" v)
(lout "Shuffled:")
(kshuffle v))
(lout "")
(with v ["A","B","C","D","E","F","G","H"]
(lout "Original:\n" v)
(lout "Shuffled:")
(kshuffle (cp v))
// Transd has a built-in function that performs the same
// kind of random shuffle
(lout "Built-in shuffle:")
(lout (shuffle v)))
)
}</syntaxhighlight>
{{out}}
<pre>
Original:
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Shuffled:
[20, 60, 100, 80, 70, 10, 50, 90, 40, 30]
Original:
["A", "B", "C", "D", "E", "F", "G", "H"]
Shuffled:
["G", "A", "D", "B", "F", "E", "C", "H"]
Built-in shuffle:
["A", "E", "C", "H", "G", "F", "B", "D"]
</pre>
=={{header|TUSCRIPT}}==
<
oldnumbers=newnumbers="",range=20
LOOP nr=1,#range
Line 3,969 ⟶ 5,178:
ENDLOOP
PRINT "after ",newnumbers</
{{out}}
<pre>
Line 3,977 ⟶ 5,186:
=={{header|uBasic/4tH}}==
<syntaxhighlight lang="text">PRINT "before:"
FOR L = 0 TO 51
@(L) = L
Line 3,998 ⟶ 5,207:
END
100 @(POP()) = POP() : @(POP()) = POP() : RETURN</
{{out}}
<pre>before:
Line 4,004 ⟶ 5,213:
after:
19 4 49 9 27 35 50 11 2 29 22 48 33 15 17 42 47 28 41 18 34 21 30 39 3 8 23 12 36 26 0 46 7 44 13 14 16 40 10 25 31 32 51 24 20 38 45 6 43 1 5 37</pre>
=={{header|Uiua}}==
{{works with|Uiua|0.10.0-dev.1}}
Build pairs of indexes to be swapped then apply these as a fold.
<syntaxhighlight lang="Uiua">
Knuth ← ∧(⍜⊏⇌)≡(⊟⌊×⚂.)⇌↘1⇡⧻.
Knuth ⇡10
</syntaxhighlight>
Typical output:
<pre>
[3 0 6 5 7 8 4 1 9 2]
</pre>
=={{header|UNIX Shell}}==
{{works with|ksh93}}
{{works with|pdksh}}
<
function shuffle {
integer i j t
Line 4,027 ⟶ 5,249:
set -A array 11 22 33 44 55 66 77 88 99 110
shuffle
echo "${array[@]}"</
=={{header|Ursala}}==
This function works on lists of any type and length, including character strings.
<
test program:
<
example = shuffle 'abcdefghijkl'</
{{out}}
<pre>'keacfjlbdigh'</pre>
=={{header|VBA}}==
<
Dim t As Variant, i As Integer
If Not IsMissing(a) Then
Line 4,088 ⟶ 5,310:
Debug.Print "After: ";
For Each i In f: Debug.Print i;: Next i: Debug.Print
End Sub</
After:
Before: 10
Line 4,101 ⟶ 5,323:
After: a This testis
</pre>
=={{header|VBScript}}==
;Implementation
<syntaxhighlight lang="vb">
function shuffle( a )
dim i
Line 4,122 ⟶ 5,345:
a = b
b = tmp
end sub</
;Invocation
<
a = array( 1,2,3,4,5,6,7,8,9)
wscript.echo "before: ", join( a, ", " )
Line 4,137 ⟶ 5,360:
wscript.echo "after: ", join( a, ", " )
shuffle a
wscript.echo "after: ", join( a, ", " )</
{{out}}
<pre>
Line 4,154 ⟶ 5,377:
The output will be inserted in current edit buffer.
<
#90 = Time_Tick // seed for random number generator
#99 = 20 // number of items in the array
Line 4,195 ⟶ 5,418:
#93 = 0x7fffffff % 48271
#90 = (48271 * (#90 % #92) - #93 * (#90 / #92)) & 0x7fffffff
Return ((#90 & 0xffff) * #91 / 0x10000)</
{{out}}
<pre>Before:
Line 4,201 ⟶ 5,424:
After:
9 13 8 18 10 1 17 15 0 16 14 19 3 2 7 11 6 4 5 12 </pre>
=={{header|V (Vlang)}}==
Updated to Vlang version 0.2.2
<syntaxhighlight lang="go">import rand
import rand.seed
fn shuffle(mut arr []int) {
for i := arr.len - 1; i >= 0; i-- {
j := rand.intn(i + 1)
arr[i], arr[j] = arr[j], arr[i]
}
println('After Shuffle: $arr')
}
fn main() {
seed_array := seed.time_seed_array(2)
rand.seed(seed_array)
mut arr := [6, 9, 1, 4]
println('Input: $arr')
shuffle(mut arr)
shuffle(mut arr)
println('Output: $arr')
}
</syntaxhighlight>
{{out}}
<pre>Input: [6, 9, 1, 4]
After Shuffle: [6, 1, 4, 9]
After Shuffle: [4, 9, 1, 6]
Output: [4, 9, 1, 6]</pre>
=={{header|Wren}}==
<syntaxhighlight lang="wren">import "random" for Random
var rand = Random.new()
var knuthShuffle = Fn.new { |a|
var i = a.count - 1
while (i >= 1) {
var j = rand.int(i + 1)
var t = a[i]
a[i] = a[j]
a[j] = t
i = i - 1
}
}
var tests = [ [], [10], [10, 20], [10, 20, 30] ]
for (a in tests) {
var b = a.toList // store original order
knuthShuffle.call(a)
System.print("%(b) -> %(a)")
}</syntaxhighlight>
{{out}}
Sample run:
<pre>
[] -> []
[10] -> [10]
[10, 20] -> [20, 10]
[10, 20, 30] -> [30, 10, 20]
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">proc Shuffle(Array, Items, BytesPerItem);
int Array, Items, BytesPerItem;
int I, J;
char Temp(8);
[for I:= Items-1 downto 1 do
[J:= Ran(I+1); \range [0..I]
CopyMem(Temp, Array+I*BytesPerItem, BytesPerItem);
CopyMem(Array+I*BytesPerItem, Array+J*BytesPerItem, BytesPerItem);
CopyMem(Array+J*BytesPerItem, Temp, BytesPerItem);
];
];
string 0; \use zero-terminated strings
int A; char B; real C;
int I;
[A:= [1, 2, 3, 4, 5];
Shuffle(A, 5, 4 \bytes per int\);
for I:= 0 to 5-1 do
[IntOut(0, A(I)); ChOut(0, ^ )];
CrLf(0);
B:= "12345";
Shuffle(B, 5, 1 \byte per char\);
for I:= 0 to 5-1 do
[ChOut(0, B(I)); ChOut(0, ^ )];
CrLf(0);
C:= [1., 2., 3., 4., 5.];
Shuffle(addr C(0), 5, 8 \bytes per real\);
for I:= 0 to 5-1 do
[RlOut(0, C(I)); ChOut(0, ^ )];
CrLf(0);
A:= [10];
Shuffle(A, 1, 4 \bytes per int\);
for I:= 0 to 1-1 do
[IntOut(0, A(I)); ChOut(0, ^ )];
CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
2 4 1 5 3
1 3 4 5 2
5.00000 4.00000 2.00000 1.00000 3.00000
10
</pre>
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: https://www.rosettacode.org/wiki/Ramsey%27s_theorem
// by Jjuanhdez, 06/2022
dim array(52)
for i = 1 to arraysize(array(),1) : array(i) = i : next i
print "Starting array"
for i = 1 to arraysize(array(),1)
print array(i) using "####";
next i
KnuthShuffle(array())
print "\n\nAfter Knuth shuffle downwards"
for i = 1 to arraysize(array(),1)
print array(i) using "####";
next i
print
end
sub KnuthShuffle(a())
local i, j, t, lb, ub
lb = 1
ub = arraysize(a(),1) - lb
for i = lb to ub
j = round(ran(i +1))
t = a(lb + i)
a(lb + i) = a(lb + j)
a(lb + j) = t
next i
end sub</syntaxhighlight>
=={{header|zkl}}==
Two versions, imperative and functional, same results.
xs has to be a mutable list.
<syntaxhighlight lang
foreach i in ([xs.len()-1..1,-1]){ xs.swap(i,(0).random(0,i+1)) }
xs
}
fcn kshufflep(xs
[xs.len()-1..1,-1].pump(Void,'wrap(i){ xs.swap(i,(0).random(0,i+1)) })
xs
}</syntaxhighlight>
<pre>
var ns=(1).pump(10,List).copy() // [1..10] made mutable
|