The Fisher-Yates shuffle#
We want to implement a shuffle.
A shuffle takes a sequence and rearranges the items in it randomly in place; each possibly arrangement has equal probability, i.e., the distribution of possible permutations is uniform.
We’ll implement the Fisher-Yates shuffle, as modernized by Don Knuth and Richard Durstenfeld. Here’s the pseudocode from Wikipedia:
-- To shuffle an array a of n elements (indices 0..n-1):
for i from n−1 downto 1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[j] and a[i]
Pseudocode is almost code, but it’s a little less formal—a little less interested in the details of how things work. No programming language has exactly the syntax above, but it clearly communicates the idea to a human. It’s also common to write prose-based instructions. Here’s the same idea.
To shuffle a sequence of n elements (0-based indexing):
- For each index
ifrom the last (indexn-1) element to the second (index1):
Let
jbe a number between0andi, inclusiveSwap element
iand elementj.
So the last element (index n-1) could swap with any element in the list—including itself! Then the second-to-last element (index n-2) could swap with anything but the already-swapped last element. The third-to-last (index n-3) could swap with anything but those last two elements. When we get down to the second element (index 1), it could swap with index 0 or itself. Our loop never touches index 0 directly in i—only (possibly) in j.
Here’s an implementation in Python. What can you do to convince yourself that it’s correct?