Fisher-Yates shuffle
Background
The Fisher–Yates shuffle produces a uniformly random permutation of a sequence in time and in place. Walking from the last index down to the first, it swaps each element with a uniformly chosen element at or before it. Every one of the permutations is equally likely — which naive "swap each with a random index in " approaches fail to guarantee.
Problem statement
Implement fisher_yates_shuffle(arr, seed=None) returning a shuffled copy of arr:
Use np.random.default_rng(seed) for the random indices.
Input
arr— a sequence (list ornp.ndarray) of lengthn.seed—intorNone, RNG seed for reproducibility.
Output
An np.ndarray of length n: a permutation of arr. The input must not be mutated.
Examples
Example 1
Input: arr = [1, 2, 3, 4], seed = 0
Output: a length-4 permutation of {1, 2, 3, 4} (e.g. [3, 1, 4, 2]); same seed always gives the same result
Explanation: the algorithm swaps each position with a uniformly chosen earlier-or-equal position, yielding a uniformly random reordering. Fixing the seed makes the output deterministic.
Constraints
- The chosen index at step must be drawn from inclusive (so an element can stay in place).
- Operate on a copy — do not modify the caller's array.
- The result is always a permutation (same multiset of elements).
Notes
- Drawing from (not ) is exactly what makes the shuffle uniform; the common bug of using biases the distribution.
- It is the algorithm behind
np.random.shuffleandrandom.shuffle.
This problem ships 5 hidden tests. They run in your browser via Pyodide — no backend, no submission queue. Press ▶ Run tests to execute.
- •Result is a permutation of the input
- •Reproducible with the same seed
- •Input array is not mutated
- •Length is preserved
- •Uniformity: each element lands in each position about equally