Home page.


Here is an example of shuffling.

With a zero-based permutation named p whose size is 15, the statement p.shuffle (false, 4, 9) means that the element in position 0 is moved to position 4, and the element in position 1 is moved to position 9. The step is then defined as 9 − 4 = 5. It is not a problem if the step is zero or negative.

Each successive element from the source is placed, into the destination, 5 (the step size) positions beyond the one previously placed, with the count wrapping around the end modularly. If the desired position is already in use, the next higher-numbered vacant space is selected instead. This "next higher-numbered" placement collision policy is what makes this shuffle an out_shuffle; it is specified by the boolean parameter of false.

The permutation size need not be a multiple of the step; if these two numbers happen to be relatively prime, the out_shuffle will give the same result as the in_shuffle.

table 1 — out_shuffle
position: 01234 56789 1011121314
arbitrary permutation: 81171213914601452103
shuffle (false, 4, 9): 96538121021113414107
unshuffle (false, 4, 9): 81171213914601452103

Of course, p.unshuffle (false, 4, 9) precisely undoes p.shuffle (false, 4, 9).

Here is an elaboration of how p.shuffle (false, 4, 9) is figured:

table 2 — shuffle (false, 4, 9)
elementold
position
new
position
comment
8 0 4by parameter
11 1 9by parameter
7 2149 + 5 = 14
12 3 514 + 5 = 19 → 4, in use; add 1
13 4105 + 5 = 10
9 5 010 + 5 = 15 → 0
1 6 60 + 5 = 5, in use; add 1
4 7116 + 5 = 11
6 8 111 + 5 = 16 → 1
0 9 71 + 5 = 6, in use; add 1
1410127 + 5 = 12
511 212 + 5 = 17 → 2
212 82 + 5 = 7, in use; add 1
1013138 + 5 = 13
314 313 + 5 = 18 → 3


For an in_shuffle, the boolean parameter is true rather than false, and the placement collision policy becomes "next lower-numbered". Example:

table 3 — in_shuffle
position: 01234 56789 1011121314
arbitrary permutation: 81171213914601452103
shuffle (true, 4, 9): 20112810144131135697
unshuffle (true, 4, 9): 81171213914601452103

table 4 — shuffle (true, 4, 9)
elementold
position
new
position
comment
8 0 4by parameter
11 1 9by parameter
7 2149 + 5 = 14
12 3 314 + 5 = 19 → 4, in use, subtract 1
13 4 83 + 5 = 8
9 5138 + 5 = 13
1 6 213 + 5 = 18 → 3, in use, subtract 1
4 7 72 + 5 = 7
6 8127 + 5 = 12
0 9 112 + 5 = 17 → 2, in use, subtract 1
1410 61 + 5 = 6
511116 + 5 = 11
212 011 + 5 = 16 → 1, in use, subtract 1
1013 50 + 5 = 5
314105 + 5 = 10


Table 5 is the one-based equivalent to zero-based table 1. Every number, including the function parameters, has been increased by 1.

table 5 — out_shuffle
position: 12345 678910 1112131415
arbitrary permutation: 912813141025711563114
shuffle (false, 5, 10): 107649132131214515118
unshuffle (false, 5, 10): 912813141025711563114


To achieve the canonical shuffles associated with a pack of playing cards, use a permutation whose size is an even number, and specify the following parameters:

table 6 — canonical shuffles
out_shuffle, zero-based:shuffle (false, 0, 2)
in_shuffle, zero-based:shuffle (true, 1, 3)
out_shuffle, one-based:shuffle (false, 1, 3)
in_shuffle, one-based:shuffle (true, 2, 4)

These functions will still give a sensible result if the size of the permutation is an odd number.


The shuffle and unshuffle operations are by position (compare reverse_position) and not by value (contrast reverse_value). A shuffle_value could be written if needed.