鱼C论坛

 找回密码
 立即注册
查看: 7170|回复: 35

[技术交流] 小练习20160124:猜数

[复制链接]
发表于 2016-1-24 23:08:54 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 冬雪雪冬 于 2016-2-1 22:41 编辑

小甲鱼在《零基础入门学习Python》第 002 讲出了一个猜数字的小游戏,是计算机出题,人来猜。

现在我们改变一下,由计算机来猜。

答题日期:1.24 ~ 1.31

规则如下:

  • 答案为随机数,范围从 1 至 100。
  • 计算机反复猜直至猜中
  • 计算猜中需要尝试的次数。
  • 共进行 100000 轮游戏,统计各个猜中次数有多少轮。并计算平均需要多少轮猜中(取 3 位小数)。
  • 程序以“添加代码文字”方式发布。
  • 输出结果见下方示例。

  1. 尝试 1 次猜中的有  1001 轮
  2. 尝试 2 次猜中的有  1943 轮
  3. 尝试 3 次猜中的有  3952 轮
  4. 尝试 4 次猜中的有  7824 轮
  5. 尝试 5 次猜中的有 15982 轮
  6. 尝试 6 次猜中的有 26929 轮
  7. 尝试 7 次猜中的有 23162 轮
  8. 尝试 8 次猜中的有 16216 轮
  9. 尝试 9 次猜中的有  2991 轮
  10. 平均 6.083 次猜中
复制代码


奖励,还是第一个答对的和最佳的奖励。题目比较简单,希望大家踊跃参加。

注:本次最佳答案不再投票评选,直接由版主选出。


评分

参与人数 1荣誉 +10 鱼币 +10 贡献 +10 收起 理由
康小泡 + 10 + 10 + 10 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-1-24 23:33:34 | 显示全部楼层

回帖奖励 +3 鱼币

抽时间试试~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2016-1-25 08:31:13 | 显示全部楼层

回帖奖励 +3 鱼币

提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-25 10:17:08 | 显示全部楼层

回帖奖励 +3 鱼币

赚鱼币

评分

参与人数 1鱼币 -2 收起 理由
康小泡 -2 请不要无意义灌水!

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-25 15:19:28 | 显示全部楼层

回帖奖励 +3 鱼币

第一次做题目 来试试
  1. import random
  2. #新建空列表,用于存放猜数字的记数
  3. count=[]

  4. #定义猜数字函数
  5. def funC():
  6.     a=int(random.uniform(1,100))
  7.     b=int(random.uniform(1,100))
  8.     for i in range(1,11):
  9.         if b==a:
  10.             break
  11.         else:
  12.             b=int(random.uniform(1,100))
  13.     count.append(int(i))

  14. #循环执行100000次   
  15. for j in range(0,100000):
  16.     funC()

  17. #定义猜中次数的计数器
  18. a1=0
  19. a2=0
  20. a3=0
  21. a4=0
  22. a5=0
  23. a6=0
  24. a7=0
  25. a8=0
  26. a9=0
  27. list1=[]

  28. #判断猜中次数
  29. for m in range(len(count)):
  30.     if count[m]==1:
  31.         a1+=1
  32.     elif count[m]==2:
  33.         a2+=1
  34.     elif count[m]==3:
  35.         a3+=1
  36.     elif count[m]==4:
  37.         a4+=1
  38.     elif count[m]==5:
  39.         a5+=1
  40.     elif count[m]==6:
  41.         a6+=1
  42.     elif count[m]==7:
  43.         a7+=1
  44.     elif count[m]==8:
  45.         a8+=1
  46.     elif count[m]==9:
  47.         a9+=1
  48. list1.extend([a1,a2,a3,a4,a5,a6,a7,a8,a9])

  49. #计算平均值
  50. sum= (a1+a2+a3+a4+a5+a6+a7+a8+a9)
  51. pjz=sum/(max(list1))

  52. #输出
  53. print('尝试 1 次猜中的有 %d 轮'%a1)
  54. print('尝试 2 次猜中的有 %d 轮'%a2)
  55. print('尝试 3 次猜中的有 %d 轮'%a3)
  56. print('尝试 4 次猜中的有 %d 轮'%a4)
  57. print('尝试 5 次猜中的有 %d 轮'%a5)
  58. print('尝试 6 次猜中的有 %d 轮'%a6)
  59. print('尝试 7 次猜中的有 %d 轮'%a7)
  60. print('尝试 8 次猜中的有 %d 轮'%a8)
  61. print('尝试 9 次猜中的有 %d 轮'%a9)
  62. print ('平均 %.3f 次猜中'%pjz)
复制代码

评分

参与人数 1鱼币 +4 收起 理由
康小泡 + 4

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-25 16:53:18 | 显示全部楼层

回帖奖励 +3 鱼币

呼呼,占位子
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-25 17:13:54 | 显示全部楼层

回帖奖励 +3 鱼币

我只是想要奖励,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-25 22:03:49 | 显示全部楼层

回帖奖励 +3 鱼币

这几天被c++折磨疯了,今天用python编程又再次体验到了愉快的感觉~
这次感觉重点是在调试上(因为有点小激动所以,注释写的有点多)
猜数用的是二分法,调试发现二分法不能取得上下两端点的值,因此把上限maxNum放大了2,成功运行~
  1. import random
  2. gesTimes = [0,0,0,0,0,0,0]#每玩一次,猜的次数统计表
  3. gameTimes = 100000 #玩的总轮数
  4. for z in range(gameTimes):
  5.     maxNum = 102#经调试后确定的上限值->100+2
  6.     minNum = 0
  7.     ans = random.randint(1,100) #1,100的随机数
  8.     playTime = 1#每轮猜的次数
  9.     gesNum = (maxNum - minNum)/2
  10.     #二分法猜数
  11.     while ans != gesNum :
  12.         if gesNum > ans:#如果大了则要变小
  13.             maxNum = gesNum
  14.             gesNum -= (maxNum - minNum)//2#变小多少
  15.         else:#如果小了则要变大
  16.             minNum = gesNum
  17.             gesNum += (maxNum - minNum)//2#变大多少
  18.         playTime += 1
  19.         #调试代码(可以屏蔽)
  20.         if 10 <playTime:
  21.             print("error:",ans) #看看有哪个值漏了
  22.             break
  23.     #录表
  24.     for i in range(7):
  25.         if playTime == (i+1) :
  26.             gesTimes[i] += 1
  27.             break
  28. #验证统计表中总数是否与游戏总轮数对应(可以屏蔽)
  29. Sum = 0
  30. for i in gesTimes:
  31.     Sum += i
  32. print("统计次数总和:",Sum)

  33. #输出结果
  34. suum = 0
  35. for i in range(7):
  36.     z = i + 1
  37.     suum += z*gesTimes[i]
  38.     print("尝试 %d 猜中的有 %d 轮"%(z,gesTimes[i]))
  39. print("平均 %2.3f 次猜中"%(suum/gameTimes)) #%2.3f控制精度
复制代码


运行结果:
  1. 统计次数总和: 100000
  2. 尝试 1 猜中的有 1007 轮
  3. 尝试 2 猜中的有 2011 轮
  4. 尝试 3 猜中的有 3954 轮
  5. 尝试 4 猜中的有 8168 轮
  6. 尝试 5 猜中的有 15844 轮
  7. 尝试 6 猜中的有 31924 轮
  8. 尝试 7 猜中的有 37092 轮
  9. 平均 5.800 次猜中
复制代码

评分

参与人数 2荣誉 +5 鱼币 +9 收起 理由
冬雪雪冬 + 5 + 5 第一答对奖
康小泡 + 4

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 08:54:17 | 显示全部楼层

回帖奖励 +3 鱼币

过来看看,给楼主增增人气!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 10:33:41 | 显示全部楼层

回帖奖励 +3 鱼币

我来试试~
  1. import random

  2. #参数
  3. gameRound = 100000 #运行轮数
  4. bottom = 1 #猜数区间的下限
  5. top = 100 #猜数区间的上限

  6. #猜数并得出结果
  7. result = [] #用来储存结果
  8. for temp in range(gameRound):
  9.     attempt = 0 #初始化尝试次数
  10.     b = bottom
  11.     t = top
  12.     secret = random.randint(b,t) #生成随机数作为答案
  13.     while True:
  14.         guess = random.randint(b,t) #开猜
  15.         attempt += 1
  16.         if guess > secret: #猜大了
  17.             t = guess - 1
  18.         elif guess < secret: #猜小了
  19.             b = guess + 1
  20.         elif guess == secret : #猜对了
  21.             break
  22.     result.append(attempt) #储存结果

  23. #输出
  24. for n in range(min(result),max(result)+1):
  25.     if n in result:
  26.         print('尝试 %d 次猜中的有 %d 轮'%(n,result.count(n)))
  27. print('平均 %.3f 次猜中'%(sum(result)/len(result)))
复制代码


运行结果
  1. 尝试 1 次猜中的有 987 轮
  2. 尝试 2 次猜中的有 2039 轮
  3. 尝试 3 次猜中的有 3842 轮
  4. 尝试 4 次猜中的有 6538 轮
  5. 尝试 5 次猜中的有 9886 轮
  6. 尝试 6 次猜中的有 13280 轮
  7. 尝试 7 次猜中的有 14873 轮
  8. 尝试 8 次猜中的有 14337 轮
  9. 尝试 9 次猜中的有 12342 轮
  10. 尝试 10 次猜中的有 8990 轮
  11. 尝试 11 次猜中的有 5996 轮
  12. 尝试 12 次猜中的有 3583 轮
  13. 尝试 13 次猜中的有 1856 轮
  14. 尝试 14 次猜中的有 852 轮
  15. 尝试 15 次猜中的有 363 轮
  16. 尝试 16 次猜中的有 151 轮
  17. 尝试 17 次猜中的有 50 轮
  18. 尝试 18 次猜中的有 27 轮
  19. 尝试 19 次猜中的有 6 轮
  20. 尝试 20 次猜中的有 1 轮
  21. 尝试 21 次猜中的有 1 轮
  22. 平均 7.460 次猜中
复制代码

评分

参与人数 2荣誉 +5 鱼币 +9 贡献 +5 收起 理由
冬雪雪冬 + 5 + 5 + 5 最佳奖
康小泡 + 4

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 11:08:37 | 显示全部楼层

回帖奖励 +3 鱼币

顶一个。上次写的不好。这次继续加油
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 12:33:55 | 显示全部楼层

回帖奖励 +3 鱼币

本帖最后由 wei_Y 于 2016-1-26 12:35 编辑
  1. import random


  2. def ran_result():
  3.     # 生成结果。
  4.     for i in range(100000):
  5.         yield random.randint(1, 100)

  6. def run():
  7.     guess_result = []
  8.     def guess(init, i, init_max=100, init_min=1, count=1):
  9.         # 猜测。
  10.         if init == i:
  11.             guess_result.append(count)
  12.             return
  13.         elif init < i:
  14.             init_min = init
  15.         elif init > i:
  16.             init_max = init
  17.         # 纯随机。
  18.         init = random.randint(init_min, init_max)
  19.         guess(init, i, init_max=init_max, init_min=init_min, count=count+1)
  20.    
  21.     for x in ran_result():
  22.         guess(random.randint(1, 100), x)

  23.     return guess_result

  24. def count_result():
  25.     # 统计。
  26.     result = run()
  27.     # 效率低,可修改最大值。
  28.     count = [0 for i in range(max(result))]
  29.     for x in result:
  30.         count[x-1] += 1
  31.     for i in range(len(count)):
  32.         print("尝试 %d  次猜中的有 %d 轮" % (i+1, count[i]))
  33.     print("平均需要: %.5f次" % (sum(map(lambda x: x*int(count.index(x))+1, count)) / 100000))
  34.    
  35. count_result()
复制代码


我也来试试。

评分

参与人数 1鱼币 +4 收起 理由
康小泡 + 4

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 16:56:41 | 显示全部楼层

回帖奖励 +3 鱼币

本帖最后由 Lnan95 于 2016-1-30 00:16 编辑

为什么最大次数只有9?版主是用二分法做的吗?
还有 在哪里加代码编辑框啊

更新: 感谢版主解答,不过我权限太低没法回复。。做了两份,我都上传吧,一份二分法一份是最原始方法的
再次更新,修复x=99,y=100无法得出数字的bug【1.27】
第三次更新:学会了个新方法,代替了以前还要用if判断所得次数是否在dict中的笨方法(话说我最多次数是8,应该和楼主一样9次才算好吗,还是越优化越好呢)【1.30】
二分法:
  1. #二分法猜数字
  2. import random
  3. lis = {}
  4. for i in range(100000):
  5.     times = 0
  6.     y = random.randint(1,100)
  7.     x = random.randint(1,100)
  8.     rangex = [1,100]
  9.     result = 0
  10.     while True:
  11.         if x == y:
  12.             result += 1
  13.             lis.setdefault(result,0)
  14.             lis[result] += 1
  15.             break
  16.         elif x < y:
  17.             result += 1            
  18.             rangex[0] = x
  19.             x = (1/2*(x+rangex[1]+1))//1
  20.         elif  x > y:
  21.             result += 1
  22.             rangex[1] = x
  23.             x = (1/2*(x+rangex[0]))//1
  24. for item in lis.items():
  25.     print("尝试 %-1d 次猜中的有%6d" % item,"轮")
  26. #加权平均
  27. summary =sum(lis.values())
  28. sumvalues  = sum([key*lis[key] for key in lis.keys()])
  29. jq = sumvalues/summary
  30. print("平均 %5f 次猜中" % jq)
复制代码


常规方法:
  1. import random
  2. lis = {}
  3. for i in range(1000):
  4.     times = 0
  5.     y = random.randint(1,100)
  6.     x = random.randint(1,100)
  7.     rangex = [1,100]
  8.     result = 0
  9.     while True:
  10.         if x == y:
  11.             result += 1
  12.             lis.setdefault(result,0)
  13.             lis[result] += 1
  14.             break
  15.         elif x < y:
  16.             result += 1
  17.             rangex[0] = x + 1
  18.             x = random.randint(rangex[0],rangex[1])
  19.         elif  x > y:
  20.             result += 1
  21.             rangex[1] = x -1
  22.             x = random.randint(rangex[0],rangex[1])
  23. for item in lis.items():
  24.     print("尝试 %-2d 次猜中的有%6d" % item,"轮")
  25. #加权平均
  26. summary =sum(lis.values())
  27. sumvalues  = sum([key*lis[key] for key in lis.keys()])
  28. jq = sumvalues/summary
  29. print("平均 %5f 次猜中" % jq)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-26 17:28:23 | 显示全部楼层

回帖奖励 +3 鱼币

我刚看到题目,难道已经有这么多人已经写完了!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-27 13:13:16 | 显示全部楼层

回帖奖励 +3 鱼币

看看
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-1-27 14:04:23 | 显示全部楼层

回帖奖励 +3 鱼币

尽量尝试一下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-27 14:18:00 | 显示全部楼层
强迫症。。。再发个2.0版。。。
  1. import random

  2. #参数
  3. gameRound = 100000 #运行轮数
  4. bottom = 1 #猜数区间的下限
  5. top = 100 #猜数区间的上限

  6. #猜数并得出结果
  7. result = [] #用来储存结果
  8. for temp in range(gameRound):
  9.     attempt = 0 #初始化尝试次数
  10.     b = bottom
  11.     t = top
  12.     secret = random.randint(b,t) #生成随机数作为答案
  13.     while True:
  14.         guess = (b+t) // 2 #开猜
  15.         attempt += 1
  16.         if guess > secret: #猜大了
  17.             t = guess - 1
  18.         elif guess < secret: #猜小了
  19.             b = guess + 1
  20.         elif guess == secret : #猜对了
  21.             break
  22.     result.append(attempt) #储存结果

  23. #输出
  24. for n in range(min(result),max(result)+1):
  25.     if n in result:
  26.         print('尝试 %d 次猜中的有 %d 轮'%(n,result.count(n)))
  27. print('平均 %.3f 次猜中'%(sum(result)/len(result)))
复制代码

运行结果(这次貌似猜的快些。。。):
  1. 尝试 1 次猜中的有 1037 轮
  2. 尝试 2 次猜中的有 1992 轮
  3. 尝试 3 次猜中的有 4045 轮
  4. 尝试 4 次猜中的有 8096 轮
  5. 尝试 5 次猜中的有 16005 轮
  6. 尝试 6 次猜中的有 31935 轮
  7. 尝试 7 次猜中的有 36890 轮
  8. 平均 5.794 次猜中
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-27 14:46:54 | 显示全部楼层

回帖奖励 +3 鱼币

import random
secret = random.randint(1, 100)
result = [0]*100
for i in range(0,100000):
    count = 0
    guess = 0
    num_max = 100
    num_min = 0
    while guess != secret:
        if guess < secret:
            num_min = guess
            guess = random.randint(guess+1, num_max)
        else:
            num_max = guess
            guess = random.randint(num_min+1, guess)
        count += 1
    result[count] += 1
for j in range(1,100):
    if result[j] != 0:
        print('尝试 %2d 次猜中的有 %7d 轮'%(j, result[j]))
这样可以吗………………
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-27 15:21:01 | 显示全部楼层

回帖奖励 +3 鱼币

本帖最后由 零度非安全 于 2016-1-29 22:52 编辑

这是我的最终答案

  1. import random
  2. TryCount = [] #首先设一个空列表,用来放尝试的次数
  3. Sumnumber = 0 #用来存放所有轮尝试的次数

  4. def BinarySearch(answer,number): #定义一个函数,用来记录每轮猜测的次数
  5.     count = 0 #统计尝试的次数
  6.     low = 1
  7.     height = 100
  8.     while low < height: #利用折半查找法进行查找,折半查找的效率更高些
  9.         count += 1 #每次进行判断完count的次数自增1
  10.         number = (low + height) // 2
  11.         if number == answer:
  12.             break #若相等,则break终止循环并将count值返回
  13.         elif number < answer:
  14.             low = number + 1 #若小于,则在右半部分查找
  15.         else:
  16.             height = number - 1 #若大于,则在左半部分查找
  17.     return count

  18. for i in range(1,100001): #题目要求进行100000轮猜测游戏
  19.     number = 0
  20.     answer = random.randint(1,100) #在1~100之间取随机数
  21.     TryCount.append(BinarySearch(answer,number)) #调用BinarySearch()函数,并将返回值依次压入列表中

  22. for j in range(1,10): #经过多次测试,每次都是10次之内
  23.     while j in TryCount:
  24.         Sumnumber += j * TryCount.count(j)
  25.         print('尝试%d次猜中的有%5d轮'%(j,TryCount.count(j)))
  26.         break

  27. print('平均%.3f次猜中'%(Sumnumber/100000))
复制代码


附上3张测试图

1.png

2.png

3.png

评分

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

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-27 16:46:03 | 显示全部楼层

回帖奖励 +3 鱼币

数组不会实现。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-7-28 20:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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