鱼C论坛

 找回密码
 立即注册
查看: 3501|回复: 40

[技术交流] Python:每日一题 181

[复制链接]
发表于 2018-7-4 10:44:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 冬雪雪冬 于 2018-7-5 20:51 编辑

我们的玩法做了一下改变:

1. 楼主不再提供答案。
2. 请大家先独立思考,再参考其他鱼油的解答,这样才有助于自己编程水平的提高。开始阶段是看不到其他人的回帖的,等答题完成,开始评分时再取消限制。
3. 鼓励大家积极答题,奖励的期限为出题后24小时内。
4. 根据答案的质量给予1~3鱼币的奖励。

题目:
扑克牌洗牌大家都会,我们就用python来做个洗牌的程序,规则是将牌平分为两半,再将两部分均匀的一张摞一张合在一起,重复这个过程多次后就会发现最终牌的次序又回到洗牌前的。
先以6张牌举个例子:
原牌序就用1, 2, 3, 4, 5, 6表示
第一次洗牌,分成1, 2, 3和4, 5 ,6两部分,一张摞一张合在一起成为1, 4, 2, 5, 3, 6
第二次洗牌,变成1, 5, 4, 3, 2, 6
第三次,1, 3, 5, 2, 4, 6
第四次又变回了1, 2, 3, 4, 5, 6

现在你要编写一个函数,参数是牌的数量(要求是偶数),打印出每次洗牌后的牌的次序,直到又回到洗牌前的原始次序为止,并打印总的洗牌次数。
如牌的数量为6,则打印:
  1. 1, 4, 2, 5, 3, 6
  2. 1, 5, 4, 3, 2, 6
  3. 1, 3, 5, 2, 4, 6
  4. 1, 2, 3, 4, 5, 6
  5. 总的洗牌次数为4
复制代码
0.jpg

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-4 10:51:45 | 显示全部楼层
本帖最后由 凌九霄 于 2018-7-5 07:40 编辑
  1. import operator
  2. import random

  3. cardvalue = ('A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K')  # 牌面点数
  4. cardstyle = ('♢', '♧', '♤', '❤')  # 牌面花色

  5. card = [ s + v for s in cardstyle for v in cardvalue ][ :random.randint(1, 26) * 2 ]
  6. print('   原牌序:{0}\n'.format(','.join(card)))
  7. i = 0


  8. # 递归最善于处理这类问题

  9. def Shuffle(cardlist):
  10.     clen = len(cardlist)
  11.     global i
  12.     zcard = list(zip(cardlist[ :clen // 2 ], cardlist[ clen // 2: ]))
  13.     zcardlist = [ x for y in zcard for x in y ]
  14.     i += 1
  15.     if operator.eq(card, zcardlist):
  16.         print('第{0}次牌序:{1}'.format(i, ','.join(zcardlist)))
  17.         print('\n总计{0}次洗牌'.format(i))
  18.     else:
  19.         print('第{0}次牌序:{1}'.format(i, ','.join(zcardlist)))
  20.         Shuffle(zcardlist)


  21. Shuffle(card)
复制代码

360截图20180705073843914.jpg

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 11:30:39 | 显示全部楼层
  1. def xp(n):
  2.     # n为牌数,且必须为偶数
  3.     if n%2 != 0:
  4.         print "参数错误,牌数必须为偶数"
  5.         return
  6.     if n <=0 or n >54:
  7.         print "参数错误,牌数必须大于0,小于等于54"
  8.         return
  9.     #开始实例化牌
  10.     xhcount = 0
  11.     s = [i for i in range(1, n + 1)]  # 初始牌序组
  12.     print "初始牌序"
  13.     print s
  14.     scheck = s[:] #记录s的比较值
  15.     print "开始洗牌"
  16.    
  17.     while True:
  18.         xhcount = xhcount + 1  # 记录洗牌次数
  19.         s1 = s[:len(s) / 2]
  20.         s2 = s[len(s) / 2:]
  21.         s3 = []
  22.         for i in range(1, len(s1) + 1):
  23.             s3.append(s1[i - 1])
  24.             s3.append(s2[i - 1])
  25.         print s3
  26.         if s3 == scheck:
  27.             print "总共洗牌次数:"+str(xhcount)
  28.             break
  29.         else:
  30.             s = s3[:]
  31. if __name__ == '__main__':
  32.     xp(6)
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 12:09:35 | 显示全部楼层
本帖最后由 罗同学 于 2018-7-4 13:12 编辑

前几天看的一本小说《我的老千生涯》里好像有写,一张压一张的洗的话好像是8次就可以(小说里看来的)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 13:11:57 | 显示全部楼层
本帖最后由 罗同学 于 2018-7-4 13:17 编辑

代码如下,由于能力有限,没有考虑花色及JKQ牌,全部用数字代替牌,一副牌不算大小王的话,52张通过8次洗牌即可恢复原状。

  1. count = 0
  2. poker = []


  3. def shuffle(poker):
  4.     global count
  5.     lift = poker[0:(number // 2)]
  6.     right = poker[number // 2:number]
  7.     shuffled = []
  8.     for i in range(number // 2):
  9.         shuffled.append(lift[i])
  10.         shuffled.append(right[i])
  11.     print('洗后的牌是:', shuffled)
  12.     count += 1
  13.     if shuffled != temp:
  14.         return shuffle(shuffled)
  15.     else:
  16.         print('总洗牌%d次' % count)


  17. if __name__ == '__main__':
  18.     while True:
  19.         number = int(input('请输入扑克数量,请输入偶数:'))
  20.         if number % 2 == 0:
  21.             for i in range(number):
  22.                 poker.append(i + 1)
  23.             print('初始扑克顺序为:', poker)
  24.             temp = poker             # 记录初始牌的顺序,用于每次迭代后判断与原始牌是否相同,否则每次迭代的结果与本次迭代开始时传入参数对比永远不同,陷入无限迭代
  25.             shuffle(poker)
  26.             break
  27.         else:
  28.             print('输入数字为基数,请注意输入偶数:')
  29.             continue
复制代码

poker.zip (693 Bytes, 下载次数: 0)

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 13:19:24 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-4 13:30:07 | 显示全部楼层
本帖最后由 塔利班 于 2018-7-4 13:31 编辑
  1. def shuffle(x):
  2.     i,t,l=0,x,len(x)//2
  3.     while not(i>=1 and t==x):
  4.         q,t=t,[]
  5.         for k in range(l):
  6.             t.extend([q[k],q[k+l]])
  7.         i+=1
  8.         print(str(t).strip('[]'))
  9.     print('总的洗牌次数为%d'%i)
复制代码


限传入列表

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 14:10:07 | 显示全部楼层
  1.     n = int(input('请输入牌的张数(偶数):'))
  2.     x = list(range(1, n+1))
  3.     new_x = x
  4.     count = 0
  5.     while True:
  6.         y = new_x[:int(n/2)]
  7.         z = new_x[int(n/2):]

  8.         new_x = []
  9.         for each in zip(y, z):
  10.             new_x.extend(list(each))

  11.         print(*new_x)
  12.         count += 1
  13.         if x == new_x:
  14.             print('总的洗牌次数为%d' % count)
  15.             break
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 14:12:37 | 显示全部楼层
  1. #一次洗牌
  2. def shuffle(card_list):
  3.     n = len(card_list)
  4.     list1 = []
  5.     list2 = []
  6.     temp = []
  7.     list1 = card_list[:n//2]
  8.     list2 = card_list[n//2:]
  9.     for i in range(n//2):
  10.         temp.append(list1[i])
  11.         temp.append(list2[i])
  12.     return temp
  13.   
  14. def printCards(n):
  15.     if n%2 == 1:
  16.         print("请将函数参数设置为偶数!")
  17.     else:
  18.         card_list = []
  19.         count = 0
  20.         for i in range(n):
  21.             card_list.append(i+1)
  22.         cards = card_list[:]        #cards列表记录洗牌前的原始次序
  23.         while True:
  24.             card_list = shuffle(card_list)
  25.             count += 1
  26.             print(str(card_list)[1:-1])
  27.             if card_list != cards:
  28.                 continue
  29.             else:
  30.                 break
  31.         print('总的洗牌次数为',count)
复制代码

结果:
  1. >>> printCards(3)
  2. 请将函数参数设置为偶数!
  3. >>> printCards(6)
  4. 1, 4, 2, 5, 3, 6
  5. 1, 5, 4, 3, 2, 6
  6. 1, 3, 5, 2, 4, 6
  7. 1, 2, 3, 4, 5, 6
  8. 总的洗牌次数为 4
  9. >>> printCards(8)
  10. 1, 5, 2, 6, 3, 7, 4, 8
  11. 1, 3, 5, 7, 2, 4, 6, 8
  12. 1, 2, 3, 4, 5, 6, 7, 8
  13. 总的洗牌次数为 3
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 15:09:32 | 显示全部楼层
本帖最后由 天圆突破 于 2018-7-4 17:40 编辑
  1. from functools import reduce

  2. def poker(oldlst, backup=[]):
  3.     if len(oldlst)%2:
  4.         return
  5.     newlst = list()
  6.     backup.append(oldlst)
  7.     if len(backup) > 1 and backup[0] == backup[-1]:
  8.         return len(backup)-1, backup
  9.     for i in range(len(oldlst)//2):
  10.         newlst.append(oldlst[i])
  11.         newlst.append(oldlst[len(oldlst)//2+i])
  12.     return poker(newlst, backup)

  13. def main(lst):
  14.     res = poker(lst)
  15.     if res:
  16.         print(reduce(lambda x,y:x+'\n'+y,map(lambda s:(reduce(lambda a,b:str(a)+',%d'%b, s)), res[1])))
  17.         print('总的洗牌次数为%d'%res[0])

  18. if __name__ == '__main__':
  19.     main([1,2,3,4,5,6])
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 17:30:31 | 显示全部楼层
本帖最后由 晓屁屁 于 2018-7-4 17:36 编辑

def poker(num):
    list1 = []
    list2 = []
    listq = []
    listh = []
    n = 1
    for x in range(1,num+1):
        list1.append(x)
        list2.append(x)
    for y in range(len(list1)):
        if y < num/2:
            listq.append(list1[y])
        else:
            listh.append(list1[y])
    x,y = 0,0
    list1 = []
    for x in range(len(listq)):
        list1.append(listq[x])
        list1.append(listh[x])
    x,y = 0,0
    listq = []
    listh = []
    print(str(','.join([str(t) for t in list1])) )
    while list1 != list2:
        n += 1
        for y in range(len(list1)):
            if y < num / 2:
                listq.append(list1[y])
            else:
                listh.append(list1[y])
        x, y = 0, 0
        list1 = []
        for x in range(len(listq)):
            list1.append(listq[x])
            list1.append(listh[x])
        x, y = 0, 0
        listq = []
        listh = []
        print(str(','.join([str(t) for t in list1])) )
    print('总的洗牌次数为%d'%n)
if __name__ == '__main__':
    temp = input('请输入牌的数量------>')
    if temp.isdigit():
        poker(int(temp))
    else:
        print('请输入数字')

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 17:57:43 | 显示全部楼层
啊啊啊,3.6.5的切片性质好奇怪,搞了半天才弄懂。
  1. def fun (list1,list2):
  2.     list3 = []
  3.     count = 0
  4.     while len(list3) != len(list1+list2):
  5.         list3.append(list1[count])
  6.         list3.append(list2[count])
  7.         count += 1
  8.     return list3
  9. def card (num):
  10.     if num % 2 == 0:
  11.         list4 = list(range(1,num+1))
  12.         list5 = []
  13.         c = 0
  14.         while list5 != list(range(1,num+1)):
  15.                 list6 = list4[0:int(num/2)]
  16.                 list7 = list4[int(num/2):num]
  17.                 list4 = fun (list6,list7)
  18.                 list5 = list4
  19.                 print (list4)
  20.                 c += 1
  21.     else:
  22.         print ('请输入偶数!!!')
  23.     print ('洗牌的次数为 %d 次' % c)
  24. while 1 :
  25.     card (int(input('请输入牌数:')))
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 19:06:31 | 显示全部楼层
  1. '''
  2. 获取次数并显示每次的排序
  3. '''
  4. def fun( n ):
  5.     r = s = list(x+1 for x in range(n))
  6.     c = 0
  7.     while True:
  8.         c += 1
  9.         s = [s[i] for i in range(0,n,2)]+[s[i] for i in range(1,n,2)]
  10.         print(s)
  11.         if s==r:
  12.             print("总次数: ",c)
  13.             break

  14. '''
  15. 只获取次数
  16. 直觉, 并没有证明
  17. '''
  18. def get_n( n ):
  19.     c = 0
  20.     t = 1
  21.     n2 = n//2
  22.     while True:
  23.         c += 1
  24.         t = t*2 if t < n2 else t*2-n+1
  25.         if t==1:
  26.             return c

  27. def main():
  28.     n = 6
  29.     fun( n )
  30.     get_n( n )
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2018-7-4 19:42:10 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-4 21:00:34 From FishC Mobile | 显示全部楼层

def main(mn):
    if mn%2==0:
        mnum=list(range(1,mn+1))
        mtemp=[]
        mn//=2
        mco=0
        while 1:
            for mi in zip(mnum[:mn],mnum[mn:]):
                mtemp+=mi
            print(mtemp)
            mco+=1
            if mtemp[1]==2:break
            mnum,mtemp=mtemp,[]
        print("总洗牌数",mco)
n=10
main(n)


想破脑袋也想不出来怎么pythonic一些

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-5 08:34:33 | 显示全部楼层
  1. def fun(l):
  2.     a = []
  3.     num = len(l)//2
  4.     for i in range(num):
  5.         a.append(l[i])
  6.         a.append(l[i+num])
  7.    
  8.     return a

  9. def main():
  10.     n = int(input('输入一个整数:'))
  11.     l = []
  12.     count = 0
  13.     for i in range(n):
  14.         l.append(i+1)
  15.     uu = l
  16.     while True:
  17.         uu = fun(uu)
  18.         count += 1
  19.         if uu == l:
  20.             break
  21.         else:
  22.             print(count,':',uu)
  23.            
  24.     print(count, ':', uu)
  25.     print('总洗牌数为%d' %count)

  26. if __name__ == '__main__':
  27.     main()

复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-5 11:03:46 | 显示全部楼层
Car=[1,2,3,4,5,6,7,8,9,10,'J','Q','K','A']
Car1=[1,2,3,4,5,6,7,8,9,10,'J','Q','K','A']
print(Car)
print('开始洗牌')
bit=1
numb=0
while bit:
    a=Car[:len(Car)//2]
    b=Car[len(Car)//2:]
    Car.clear()
    i=0
    while i<len(a):
        Car.append(a[i])
        Car.append(b[i])
        i+=1
    numb+=1
    print(Car)
    if Car==Car1:
        bit=0
        print('洗牌结束,总的洗牌次数为%d'%numb)


评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-5 12:33:09 From FishC Mobile | 显示全部楼层
answer181.jpg

点评

请用文本的方式发代码  发表于 2018-7-5 12:35

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-5 13:35:05 | 显示全部楼层
  1. def shuffle(s):
  2.         res=[]
  3.         for i in range(len(s)//2):
  4.                 res.append(s[i])
  5.                 res.append(s[i+len(s)//2])       
  6.         return res

  7. k=6
  8. s=[i for i in range(1,k+1)]
  9. ss,n=s,0
  10. while True:
  11.         n+=1
  12.         ss=shuffle(ss)
  13.         print(str(ss)[1:-1])       
  14.         if ss==s:
  15.                 print("总的洗牌次数为%d"%n)
  16.                 break
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-5 17:06:07 | 显示全部楼层
  1. def xp(n):
  2.         card=[]
  3.         for i in range(1,n+1):
  4.                 card.append(i)
  5.         card2=[]
  6.         count=0
  7.         s=int(n/2)
  8.         p1=card[:s]
  9.         p2=card[s:]
  10.         while True:
  11.                 for each in range(s):
  12.                         card2.append(p1[each])
  13.                         card2.append(p2[each])
  14.                 print(card2)
  15.                 count +=1
  16.                 if card2==card:
  17.                         print('洗牌次数为%d次' % count)
  18.                         break
  19.                 p1=card2[:s]
  20.                 p2=card2[s:]
  21.                 card2=[]
  22. n=int(input('请输入一个偶数'))
  23. xp(n)
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
冬雪雪冬 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 20:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表