一副牌被分成两等分,上半叠在左手,下半叠在右手。接下来,卡被完全交错,右半部的最上卡正好插在左半部的最上卡之后,右半部的第二张卡正好插在左半部的第二张卡之后,等等(注意这个过程保留了牌组上下卡的位置)
令s(n)是大小为n的牌组恢复其原始配置所需的最小连续重复洗牌次数,其中n是一个正偶数。
令人惊讶的是,一副52张牌的标准扑克只要完全洗8次牌将就会返回到原来的配置,所以s(52)=8
可以证实一个86张牌的牌组也会在洗8次牌后恢复到原来的配置 。
满足s(n)=8的所有n值之和s(n)=412
求满足s(n)=60的所有n值之和

下面的简单程序可以测试

def sf(x):
 return [ x[:len(x)//2][i] if j%2==0 else x[len(x)//2:][i] for i in range(0,len(x)//2) for j in range(2)]

def test(n):
 c=0
 x=list(range(1,n+1))
 xm=[i for i in x]
 while True:
  c+=1
  xm=sf(xm)
  if x==xm:return c    

>>> test(52)
8
>>> test(84)
82
>>> test(86)
8
>>> [i for i in range(2,300,2) if test(i)==8]
[18, 52, 86, 256]
>>> sum([i for i in range(2,300,2) if test(i)==8])
412
>>> [i for i in range(2,300,2) if test(i)==60]
[62, 144, 176, 184, 226, 288]

通过分析每轮洗牌后牌的变化,相邻两牌的间隔从n/2开始,每次间隔都缩小1半,如果遇到奇数,则加上n-1之后再缩小,一直下去到间隔等于1之后就恢复原状了。因此得到如下快一点的版本

def gen(x):
 n=x
 c=0
 while n>1:
  if n%2==0:n//=2 ;c+=1 #;print(n)
  else: n+=(x-1)
 return c

def s(n):
 return [i for i in range(2,2**n+1,2) if gen(i)==n]

>>> s(12)
[14, 36, 40, 46, 66, 92, 106, 118, 196, 274, 316, 456, 586, 820, 1366, 4096]
>>> s(13)
[8192]
>>> s(14)
[44, 130, 382, 5462, 16384]