Card Shuffler

Alice and Bob want to make a card shuffling machine for their poker club. The problem is that they propose different algorithms and thus can't decide which one to apply:

  • Alice: For each card (going from left to right), swap it with one of the cards on its right, including itself.
  • Bob: For each card (going from left to right), swap it with any other card.

Whose algorithm is better, or does it really matter?

Alice Bob Both are good

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

1 solution

Christopher Boo
Feb 4, 2017

The answer might be counter-intuitive at first. Why is Bob's algorithm bad? Couldn't it generate all permutations? The answer is yes; it could generate all permutations, but not evenly. There is a total of n n n^n moves, but there are only n ! n! permutations. Since n ! n! doesn't divide n n n^n in general, not all permutations have equal chance to be generated.

Now we are convinced that Bob's algorithm is bad, but how bad it is? Noticed that if a card is swapped to its left, it couldn't go left any further!

Still not convinced? Let the data do the speaking.

The left image is Alice's algorithm and the right one is Bob's. The x-axis is the numbers, and the y-axis is the position it ended up after going through the algorithm. The brighter the cell, the higher frequency the number ended up in that position. As you can see, most of the numbers ended up being on its left!

If you are interested in how the visualisation is generated, here is the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from random import randint
import matplotlib.pyplot as plt

x_data = []
y_data = []
# start simultion for distributed permutations
for simulation in range(1000):
    # perfectly sorted array
    arr = [x + 1 for x in range(1000)]
    for i in range(1000):
        r = randint(0, i) # correct way

        # swap two elements
        arr[r], arr[i] = arr[i], arr[r]

    # collect result
    for i in range(1000):
        x_data.append(arr[i])
        y_data.append(i+1)
# end simulation

# plot
fig, axs = plt.subplots(ncols = 2, sharey=True, figsize=(14, 6))
fig.subplots_adjust(hspace=0.5, left=0.07, right=0.93)
hb = axs[0].hexbin(x_data, y_data, gridsize=50, cmap='inferno')
axs[0].axis([0, 1000, 0, 1000])
axs[0].set_title("Distributed Permutation")
cb = fig.colorbar(hb, ax=axs[0])
cb.set_label('frequency')

x_data = []
y_data = []
# start simultion for biased permutations
for simulation in range(1000):
    # perfectly sorted array
    arr = [x + 1 for x in range(1000)]
    for i in range(1000):
        r = randint(0,999) # wrong way

        # swap two elements
        arr[r], arr[i] = arr[i], arr[r]

    # collect result
    for i in range(1000):
        x_data.append(arr[i])
        y_data.append(i+1)
# end simulation

# plot
fig.subplots_adjust(hspace=0.5, left=0.07, right=0.93)
hb = axs[1].hexbin(x_data, y_data, gridsize=50, cmap='inferno')
axs[1].axis([0, 1000, 0, 1000])
axs[1].set_title("Biased Permutation")
cb = fig.colorbar(hb, ax=axs[1])
cb.set_label('frequency')

plt.show()

Nice.

As a concrete example, if you do Bob's shuffle with a three-card deck, the card that starts in Position 2 has an 8/27 chance of ending up there, a 10/27 chance of ending up in Position 2, and a 1/3 chance of ending up in Position 3.

Peter Byers - 4 years, 3 months ago

Log in to reply

Right, demonstrating with small cases like this do give a clearer reasoning.

Christopher Boo - 4 years, 3 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...