抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

一、洗牌的方法

将一副牌平均分成两份进行完美洗牌法,有两种方法,如图所示:
This is a picture without description

1、顶牌洗到第1张

不考虑下半部分的牌,如果设上半部分的牌中某张牌的位置为i,那么这张牌经过完美洗牌法后位置就变成i*2-1(奇数)。
例如,第2张牌去到了第3张的位置。

2、顶牌洗到第2张

同理,上半部分的牌中某张牌的位置变成了i*2(偶数)。例如,第2张牌去到了第4张的位置。

二、考虑几个问题

1、问题1

如何运用两种完美洗牌法把第2张牌洗到第21张?

因为完美洗牌法只能把牌洗到第i*2-1(奇数)张或者第i*2(偶数)张,那么通过位置的奇偶就能知道该用哪种洗牌法了,可以采用由后往前倒推的方法。
例如,第21张是奇数,那么只能是通过i*2-1得到的,于是可以求出前一个位置i为第11张。同理可得出位置的变化为2, 3, 6, 11, 21

知道了位置的变化,就可以求出该用那种洗牌法洗牌。例如一开始黑桃A在第2张,要洗到第3张的位置,所以要采用i*2-1的方法,也就是第一种方法。

用python写的算法如下:

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
# -*- coding : utf-8 -*-

import math

#获取牌的位置变化
def get_faro_shuffle_pos(last_pos):
pos_list = [last_pos]
while last_pos is not 1:
last_pos = int(math.ceil(last_pos / 2.0))
pos_list = [last_pos] + pos_list
return pos_list

#获取洗牌的方法
#0代表第一种方法,1代表第二种方法
def get_faro_shuffle_method(pos_list):
method_list = []
for x in pos_list[1:]:
method_list.append((x + 1) % 2)
return method_list


if __name__ == "__main__":

cards = range(1, 52+1)
pos_list = get_faro_shuffle_pos(21)
print("位置变化 :", pos_list)

method_list = get_faro_shuffle_method(pos_list)
print("洗牌方法 :", method_list)

执行结果为:

1
2
位置变化 : [1, 2, 3, 6, 11, 21]
洗牌方法 : [1, 0, 1, 0, 0]

算法如此简单,以至于心算也能很快完成,毫无压力。

视频里选定的牌是在第2张,而上面的代码假定了选定的牌在第1张,那么经过一次完美洗牌后选定牌就到了第2张,就跟视频里的位置一样了。这样做能够比较容易观察出牌的位置变化。

牌的位置变化可以通过以下代码得出:

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
#coding:utf-8

#返回完美洗牌后的数组
#0代表第一种方法,1代表第二种方法
def faro_shuffle(cards, method=0):
new_cards = cards[:]
num = len(cards)
for index in range(num):
new_index = (index*2 + (index*2/num)^method) % num
new_cards[new_index] = cards[index]
return new_cards


if __name__ == "__main__":

cards = range(1, 52+1)
print("原牌的顺序:")
print(cards)

print("完美洗牌后的顺序:")
method_list = [1, 0, 1, 0, 0]
for x in method_list:
cards = faro_shuffle(cards, x)
print(cards)

执行结果为:

1
2
3
4
5
6
7
8
9
原牌的顺序:
[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]

完美洗牌后的顺序:
[27, 1, 28, 2, 29, 3, 30, 4, 31, 5, 32, 6, 33, 7, 34, 8, 35, 9, 36, 10, 37, 11, 38, 12, 39, 13, 40, 14, 41, 15, 42, 16, 43, 17, 44, 18, 45, 19, 46, 20, 47, 21, 48, 22, 49, 23, 50, 24, 51, 25, 52, 26]
[27, 40, 1, 14, 28, 41, 2, 15, 29, 42, 3, 16, 30, 43, 4, 17, 31, 44, 5, 18, 32, 45, 6, 19, 33, 46, 7, 20, 34, 47, 8, 21, 35, 48, 9, 22, 36, 49, 10, 23, 37, 50, 11, 24, 38, 51, 12, 25, 39, 52, 13, 26]
[7, 27, 20, 40, 34, 1, 47, 14, 8, 28, 21, 41, 35, 2, 48, 15, 9, 29, 22, 42, 36, 3, 49, 16, 10, 30, 23, 43, 37, 4, 50, 17, 11, 31, 24, 44, 38, 5, 51, 18, 12, 32, 25, 45, 39, 6, 52, 19, 13, 33, 26, 46]
[7, 23, 27, 43, 20, 37, 40, 4, 34, 50, 1, 17, 47, 11, 14, 31, 8, 24, 28, 44, 21, 38, 41, 5, 35, 51, 2, 18, 48, 12, 15, 32, 9, 25, 29, 45, 22, 39, 42, 6, 36, 52, 3, 19, 49, 13, 16, 33, 10, 26, 30, 46]
[7, 2, 23, 18, 27, 48, 43, 12, 20, 15, 37, 32, 40, 9, 4, 25, 34, 29, 50, 45, 1, 22, 17, 39, 47, 42, 11, 6, 14, 36, 31, 52, 8, 3, 24, 19, 28, 49, 44, 13, 21, 16, 38, 33, 41, 10, 5, 26, 35, 30, 51, 46]

由上面的执行结果可以看出,假设黑桃A一开始的位置是1,通过5次完美洗牌后位置就变成了21

2、问题2

如何精确地把一副牌分成牌数相等的两部份?

答案是不用平均分。
可能很多人会产生一个错觉,以为两叠牌的牌数相等才能进行完美洗牌法,但在这个视频中并不需要,两叠牌的牌数允许存在误差。
魔术师把牌分成两半,误差张数一般在0~2之间,也就是说两叠牌的张数差大于4张就能感觉出来了。
魔术师表演魔术时是要去掉大小王牌的,整副牌有52张,当误差为2张时,上半叠牌可能会拿到24张。为了保证把牌洗到某个位置的准确性,那么牌的最终位置最大只能为24 * 2 = 48

可能有人会问,如果魔术师用骰子得出的数字大于48怎么办?我认为这是不可能的。
因为骰子只有123456,如果投出来的两个数字都大于等于5,那么组合出的数字都大于52,魔术师会重新投骰子。
如果其中一个数字小于5,那么组合出来的数字最大是46,在安全区内。
如果投出52,魔术师会说这是25,而不会说是52

3、问题3

如何让一张牌隔着一张牌进行完美洗牌法?

这确实不难,很多年以前我上初中的时候,有一天在电视看到魔术师用了完美洗牌法,于是就买了一副牌研究,练习了一两天就成功了。
当时用的牌是两块钱一副的,练习起来比较难,如果用视频里的单车牌的话,完美洗牌是非常容易完成的。

评论