Created
May 18, 2016 15:57
-
-
Save wkw/462e456b4b89005c611fb519616232c9 to your computer and use it in GitHub Desktop.
Fisher-Yates Shuffle in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://bost.ocks.org/mike/shuffle/ | |
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle | |
function shuffle(array) { | |
var m = array.length, t, i; | |
// While there remain elements to shuffle… | |
while (m) { | |
// Pick a remaining element… | |
i = Math.floor(Math.random() * m--); | |
// And swap it with the current element. | |
t = array[m]; | |
array[m] = array[i]; | |
array[i] = t; | |
} | |
return array; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src: // https://bost.ocks.org/mike/shuffle/ | |
But here’s an interesting, if obvious, insight: the number of shuffled elements (n - m) plus the number of remaining elements (m) is always equal to n. This means we can do the entire shuffle in-place, without any extra space! We use the back of the array to store the shuffled elements, and the front of the array to store the remaining elements. We don’t care about the order of the remaining elements as long as we sample uniformly when picking! | |
To implement the in-place O(n) shuffle, then, pick a random remaining element (from the front) and place in its new location (in the back). The unshuffled element in the back is swapped to the front, where it waits for subsequent shuffling: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment