Skip to content

Commit 7457400

Browse files
committed
[Swift 4.2] Update Shuffle
1 parent 4d50254 commit 7457400

File tree

3 files changed

+4
-18
lines changed

3 files changed

+4
-18
lines changed

Shuffle/README.markdown

+2-6
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ You should see three different arrangements -- or [permutations](../Combinatoric
3333

3434
This shuffle works *in place*, it modifies the contents of the original array. The algorithm works by creating a new array, `temp`, that is initially empty. Then we randomly choose an element from the original array and append it to `temp`, until the original array is empty. Finally, the temporary array is copied back into the original one.
3535

36-
> **Note:** `random()` is a helper function that returns a random integer between 0 and the given maximum.
37-
3836
This code works just fine but it's not very efficient. Removing an element from an array is an **O(n)** operation and we perform this **n** times, making the total algorithm **O(n^2)**. We can do better!
3937

4038
## The Fisher-Yates / Knuth shuffle
@@ -45,7 +43,7 @@ Here is a much improved version of the shuffle algorithm:
4543
extension Array {
4644
public mutating func shuffle() {
4745
for i in stride(from: count - 1, through: 1, by: -1) {
48-
let j = random(i + 1)
46+
let j = Int.random(in: 0...i)
4947
if i != j {
5048
swap(&self[i], &self[j])
5149
}
@@ -56,8 +54,6 @@ extension Array {
5654

5755
Again, this picks objects at random. In the naive version we placed those objects into a new temporary array so we could keep track of which objects were already shuffled and which still remained to be done. In this improved algorithm, however, we'll move the shuffled objects to the end of the original array.
5856

59-
> **Note**: When you write `random(x)`, the largest number it will return is `x - 1`. We want to have `j <= i`, not `j < i`, so the largest number from the random number generator needs to be `i`, not `i - 1`. That's why we do `random(i + 1)`. If we didn't add that 1 to compensate, it would make some shuffle orders more likely to occur than others.
60-
6157
Let's walk through the example. We have the array:
6258

6359
[ "a", "b", "c", "d", "e", "f", "g" ]
@@ -99,7 +95,7 @@ Here is the code:
9995
public func shuffledArray(_ n: Int) -> [Int] {
10096
var a = [Int](repeating: 0, count: n)
10197
for i in 0..<n {
102-
let j = random(i + 1)
98+
let j = Int.random(in: 0...i)
10399
if i != j {
104100
a[i] = a[j]
105101
}

Shuffle/Shuffle.playground/Contents.swift

-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
//: Playground - noun: a place where people can play
22

3-
// last checked with Xcode 9.0b4
4-
#if swift(>=4.0)
5-
print("Hello, Swift 4!")
6-
#endif
7-
83
import Foundation
94

105
var list = [ "a", "b", "c", "d", "e", "f", "g" ]

Shuffle/Shuffle.playground/Sources/Shuffle.swift

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import Foundation
22

3-
/* Returns a random integer between 0 and n-1. */
4-
public func random(_ n: Int) -> Int {
5-
return Int(arc4random_uniform(UInt32(n)))
6-
}
7-
83
extension Array {
94
/*
105
Randomly shuffles the array in-place
@@ -13,7 +8,7 @@ extension Array {
138
*/
149
public mutating func shuffle() {
1510
for i in (1...count-1).reversed() {
16-
let j = random(i + 1)
11+
let j = Int.random(in: 0...i)
1712
if i != j {
1813
let t = self[i]
1914
self[i] = self[j]
@@ -29,7 +24,7 @@ extension Array {
2924
public func shuffledArray(_ n: Int) -> [Int] {
3025
var a = Array(repeating: 0, count: n)
3126
for i in 0..<n {
32-
let j = random(i + 1)
27+
let j = Int.random(in: 0...i)
3328
if i != j {
3429
a[i] = a[j]
3530
}

0 commit comments

Comments
 (0)