前些天去黄山路上,同事表演了一个“魔术”。表演方法:
由对方洗牌,洗的次数越多越好。洗好后,表演者拿起全部牌看一编,可以看牌面,但不改变牌的次序,“努力记忆”所有牌面的数值。然后交还对方。
由对方在前十张中随便选一张,告诉表演者是第几张。对方从这张牌开始,牌面数字是几,就往后数几张,然后再按照牌面数字按同样方法继续数,直到不能再继续为止,记住这张牌的数值。数牌时不让表演者看到。
然后,表演者开始利用强大的“记忆”能力开始“心算”,然后告诉对方,最后看到的数值是几。
以此证明,表演者强大的记忆力。
这里用程序来验证一下。
### 初始化扑克 ### proc init_poker {{max_n 13} {max_m 2}} { set rv [list ] for {set m 1} {$m<=$max_m} {incr m} { for {set i 1} {$i<=$max_n} {incr i} { lappend rv $i } } return $rv; } ### 随机洗牌 ### proc shuffle_poker {iv {loop 13}} { set size [llength $iv] for {set i 1} {$i<=$loop} {incr i} { set r [expr int(floor(rand()*$size))] set t [lindex $iv $r]; lset iv $r [lindex $iv 0] lset iv 0 $t set r [expr int(floor(rand()*$size))] set t [lindex $iv $r]; lset iv $r [lindex $iv end] lset iv end $t } return $iv; } proc check_result {iv {seed 0}} { set size [llength $iv] # 第seed张牌是几,就往后数几张牌,直到数到最后,不能再数为止 while {$seed<$size} { set n [lindex $iv $seed] incr seed $n } # 返回最后数到的那张牌的数值 return $n } ### 检查是否必胜 ### proc check_sure {{max_n 10} {n_poker 2}} { # 2副牌,只留下1到10的牌,随机洗牌 set poker [shuffle_poker [init_poker $max_n [expr 4*$n_poker]] [expr 4*30]] # 无论从哪张开始数,结果都回落到同一张牌上 # 殊途而同归 set rv [list] set succ 1 for {set i 0} {$i<$max_n} {incr i} { set v [check_result $poker $i] lappend rv $v if {[lindex $rv 0] != $v} { set succ 0 } } return $succ } ### 统计概率 ### proc test_sure {{max_n 10} {n_poker 2}} { set n_succ 0 set n_max 1000 for {set i 0} {$i < $n_max} {incr i} { set sure [check_sure $max_n $n_poker] if {$sure==1} {incr n_succ} } puts [format "%2d/%d: %4d %4d %6.2f%%" $max_n $n_poker \ $n_succ $n_max [expr $n_succ*1.0/$n_max*100]] } test_sure 10 1 test_sure 13 1 test_sure 10 2 test_sure 13 2 test_sure 10 3 test_sure 13 3 test_sure 4 1 test_sure 5 1 test_sure 8 1 test_sure 4 2 test_sure 5 2 test_sure 6 2 test_sure 7 2 test_sure 8 2 test_sure 4 3 test_sure 5 3 test_sure 6 3 test_sure 7 3 test_sure 8 3
统计不同玩法的成功概率,结果如下:
10/1: 428 1000 42.80% 13/1: 247 1000 24.70% 10/2: 883 1000 88.30% 13/2: 749 1000 74.90% 10/3: 969 1000 96.90% 13/3: 909 1000 90.90% 4/1: 938 1000 93.80% 5/1: 869 1000 86.90% 8/1: 611 1000 61.10% 4/2: 1000 1000 100.00% 5/2: 995 1000 99.50% 6/2: 981 1000 98.10% 7/2: 963 1000 96.30% 8/2: 938 1000 93.80% 4/3: 1000 1000 100.00% 5/3: 1000 1000 100.00% 6/3: 999 1000 99.90% 7/3: 997 1000 99.70% 8/3: 985 1000 98.50%