• Thirdpen

Fisher-Yates Shuffle

The definitive guide to unbiased array randomization

What is the Fisher-Yates Shuffle?

The Fisher-Yates shuffle (also known as the Knuth shuffle) is an algorithm for generating a random permutation of a finite sequence—in plain terms, for randomly shuffling an array. It produces an unbiased permutation: every permutation is equally likely.

Historical Context

The algorithm was first described by Ronald Fisher and Frank Yates in 1938 in their book Statistical Tables for Biological, Agricultural and Medical Research. Later, Donald Knuth popularized it in The Art of Computer Programming.

Why It Matters

Many naive shuffling algorithms produce biased results. Fisher-Yates is efficient (O(n) time complexity) and mathematically proven to be unbiased, making it the gold standard for shuffling.

How It Works

The Algorithm Steps

  1. Start with the last element in the array (index n-1)
  2. Pick a random index between 0 and the current index (inclusive)
  3. Swap the element at the current index with the element at the random index
  4. Move to the previous element (decrement index by 1)
  5. Repeat until you reach the first element

Pseudocode

// Fisher-Yates Shuffle Pseudocode
for i from n−1 downto 1 do
     j ← random integer such that 0 ≤ j ≤ i
     exchange a[j] and a[i]

Visual Demonstration

Initial Array

Implementation Examples

Modern ES6 Implementation

/**
 * Fisher-Yates Shuffle (ES6 implementation)
 * @param {Array} array - The array to shuffle
 * @returns {Array} The shuffled array (mutates original)
 */
function fisherYatesShuffle(array) {
    // Loop from last element to first
    for (let i = array.length - 1; i > 0; i--) {
        // Random index from 0 to i (inclusive)
        const j = Math.floor(Math.random() * (i + 1));
        
        // ES6 destructuring swap
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}

Hover to see explanation

Key Features

  • Uses ES6 array destructuring for clean swapping
  • Works in-place (modifies original array)
  • Returns the shuffled array for chaining
  • Time complexity: O(n)
  • Space complexity: O(1)

Traditional Implementation

/**
 * Fisher-Yates Shuffle (Traditional implementation)
 * @param {Array} array - The array to shuffle
 * @returns {Array} The shuffled array (mutates original)
 */
function fisherYatesShuffle(array) {
    var currentIndex = array.length, 
        temporaryValue, 
        randomIndex;
    
    // While there remain elements to shuffle...
    while (currentIndex !== 0) {
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
        
        // And swap it with the current element
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }
    
    return array;
}

Hover to see explanation

Key Features

  • Uses temporary variable for swapping
  • More verbose but works in all JavaScript versions
  • Same time and space complexity as ES6 version
  • Easier to debug with separate steps

Common Mistakes and Pitfalls

Naive Shuffling (Incorrect)

// ⚠️ Warning: This produces biased results!
// The sort comparator function doesn't guarantee uniform distribution
array.sort(() => Math.random() - 0.5);

This approach seems simple but produces non-uniform distributions because the sorting algorithm's comparison mechanism isn't designed for randomness.

Off-by-One Errors

// ⚠️ Common mistake - j should be ≤ i, not < i
for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * i); // Wrong!
    [array[i], array[j]] = [array[j], array[i]];
}

This excludes the possibility of an element swapping with itself, which is mathematically necessary for uniform distribution.

Applications of Fisher-Yates Shuffle

Card Games

Shuffling decks of cards in digital card games where fair distribution is critical.

Random Sampling

Selecting random subsets from larger datasets in statistical analysis.

Music Players

Creating truly random playlists where each song has equal chance of playing next.

Machine Learning

Randomizing training data batches to prevent order-based biases.

A/B Testing

Randomly assigning users to test groups in web experiments.

Cryptography

Generating random permutations for cryptographic applications.

Interactive Shuffle Tester

Test the Algorithm

Enter items (comma separated) to create an array and see the Fisher-Yates shuffle in action.

Distribution Results

Shuffle the array multiple times to see the distribution of results.

Current Array

Shuffle Steps

Shuffle steps will appear here...

© 2023 Fisher-Yates Shuffle Educational Guide

The Fisher-Yates algorithm remains the gold standard for unbiased array shuffling since 1938.