魔术实质
约瑟夫问题(Josephus problem)又称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,约瑟夫问题类似问题又称为约瑟夫环、“丢手绢问题”。
算法精解:约瑟夫(Josephus)问题 - 知乎 (zhihu.com)
实现过程
step1抽取4张牌并打乱
print(f'随机抽四张牌,分别是{cards}') random.shuffle(cards) # 随机排列 print(f'打乱顺序,当前牌池是{cards}')
step2将纸牌对折两次,撕成八张小纸片
cards += cards[::1] print(f'对折后撕开,当前牌池是{cards}')
step3根据名字字数洗牌
选择一张纸牌,然后根据自己名字的字数,取N张纸牌(N为名字字数),放在后面
count = name_length while count != 0: a = cards[0] del cards[0] cards.append(a) count -= 1 print(f'当前名字长度是{name_length},将前{name_length}张放到剩余牌的后面,当前牌池:{cards}')
step4插入前三张纸牌到中间
将选择的前三张纸牌插入整副纸牌的中间
a, b, c = cards[0], cards[1], cards[2] del cards[0], cards[0], cards[0] cards.append('d') cards.append('d') cards.append('d') cards[6], cards[7] = cards[3], cards[4] cards[3], cards[4], cards[5] = a, b, c print(f'取出3张,插在牌池中间,当前牌池{cards}')
step5取一张保留
a = cards[0] first = cards[0] del cards[0] print(f'取出第一张藏好,第一张是{a},剩余牌池{cards}')
step6南方人和北方人的操作
南方人拿走1张纸牌,北方人拿走2张纸牌,不确定是南北方则拿3张纸牌,然后将这些纸牌插入整副纸牌的中间。
if local == 'n' or local == 'N': a = cards[0] del cards[0] cards.append('d') cards[4], cards[5], cards[6] = cards[3], cards[4], cards[5] cards[3] = a sign = 1 elif local == 's' or local == 'S': a = cards[0] b = cards[1] del cards[0], cards[0] cards.append('d') cards.append('d') cards[5], cards[6] = cards[3], cards[4] cards[3], cards[4] = a, b sign = 2 else: a = cards[0] b = cards[1] c = cards[2] del cards[0], cards[0], cards[0] cards.append('d') cards.append('d') cards.append('d') cards[5], cards[6] = cards[2], cards[3] cards[2], cards[3], cards[4] = a, b, c sign = 3 print(f'根据地区,取出{sign}张牌,插在牌池中间,当前牌池:{cards}')
step7 男生和女生的操作:
男生扔掉前两张纸牌,女生扔掉第一张纸牌
if sex == 'b' or sex == 'B': del cards[0] sign = 1 elif sex == 'g' or sex == 'G': del cards[0], cards[0] sign = 2 else: sign = 0 print(f'根据性别,删除{sign}张牌,剩余牌池:{cards}')
step8见证奇迹的时刻
进行七次洗牌
count = 7 while count != 0: a = cards[0] del cards[0] cards.append(a) count -= 1 print(f'把{a}放在末尾,当前牌池:{cards}') print(f'见证奇迹的时刻,当前牌池:{cards}')
step9好运留下来,烦恼丢出去
循环执行洗牌和扔纸牌的操作,每次都将第一张纸牌放到底部,将第二张纸牌扔出去
while len(cards) != 1: temp = cards[0] del cards[0] cards.append(temp) a = cards[0] del cards[0] print(f'留下{temp},丢下{a},剩余牌池:{cards}') final = cards[0] print(f'保存的牌是{first},最后的牌是{final}')
完整代码
import random
def sort():
deck = ['A♠', '2♠', '3♠', '4♠', '5♠', '6♠', '7♠', '8♠', '9♠', '10♠', 'J♠', 'Q♠', 'K♠',
'A♣', '2♣', '3♣', '4♣', '5♣', '6♣', '7♣', '8♣', '9♣', '10♣', 'J♣', 'Q♣', 'K♣',
'A♥', '2♥', '3♥', '4♥', '5♥', '6♥', '7♥', '8♥', '9♥', '10♥', 'J♥', 'Q♥', 'K♥',
'A♦', '2♦', '3♦', '4♦', '5♦', '6♦', '7♦', '8♦', '9♦', '10♦', 'J♦', 'Q♦', 'K♦',
'Joker1', 'Joker2']
# 从完整牌组中随机选择4张牌
lt = random.sample(deck, 4)
return lt
name_length = len(input('name:'))
local = input('local(n/s)[南方n,北方s,不清楚的随便]:')
sex = input('sex(b/g)[男生b,女生g]:')
cards = sort()
print(f'随机抽四张牌,分别是{cards}')
random.shuffle(cards) # 随机排列
print(f'打乱顺序,当前牌池是{cards}')
cards += cards[::1]
print(f'对折后撕开,当前牌池是{cards}')
# 名字长度
count = name_length
while count != 0:
a = cards[0]
del cards[0]
cards.append(a)
count -= 1
print(f'当前名字长度是{name_length},将前{name_length}张放到剩余牌的后面,当前牌池:{cards}')
# 取3张,放中间
a, b, c = cards[0], cards[1], cards[2]
del cards[0], cards[0], cards[0]
cards.append('d')
cards.append('d')
cards.append('d')
cards[6], cards[7] = cards[3], cards[4]
cards[3], cards[4], cards[5] = a, b, c
print(f'取出3张,插在牌池中间,当前牌池{cards}')
# 取一张
a = cards[0]
first = cards[0]
del cards[0]
print(f'取出第一张藏好,第一张是{a},剩余牌池{cards}')
# 地方位置
if local == 'n' or local == 'N':
a = cards[0]
del cards[0]
cards.append('d')
cards[4], cards[5], cards[6] = cards[3], cards[4], cards[5]
cards[3] = a
sign = 1
elif local == 's' or local == 'S':
a = cards[0]
b = cards[1]
del cards[0], cards[0]
cards.append('d')
cards.append('d')
cards[5], cards[6] = cards[3], cards[4]
cards[3], cards[4] = a, b
sign = 2
else:
a = cards[0]
b = cards[1]
c = cards[2]
del cards[0], cards[0], cards[0]
cards.append('d')
cards.append('d')
cards.append('d')
cards[5], cards[6] = cards[2], cards[3]
cards[2], cards[3], cards[4] = a, b, c
sign = 3
print(f'根据地区,取出{sign}张牌,插在牌池中间,当前牌池:{cards}')
# 性别
if sex == 'b' or sex == 'B':
del cards[0]
sign = 1
elif sex == 'g' or sex == 'G':
del cards[0], cards[0]
sign = 2
else:
sign = 0
print(f'根据性别,删除{sign}张牌,剩余牌池:{cards}')
# 见证奇迹的时刻
count = 7
while count != 0:
a = cards[0]
del cards[0]
cards.append(a)
count -= 1
print(f'把{a}放在末尾,当前牌池:{cards}')
print(f'见证奇迹的时刻,当前牌池:{cards}')
# 好运留下来,烦恼丢出去
while len(cards) != 1:
temp = cards[0]
del cards[0]
cards.append(temp)
a = cards[0]
del cards[0]
print(f'留下{temp},丢下{a},剩余牌池:{cards}')
final = cards[0]
print(f'保存的牌是{first},最后的牌是{final}')