鱼C论坛

 找回密码
 立即注册
查看: 650|回复: 21

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

[复制链接]
最佳答案
65 
发表于 2018-1-12 09:44:01 | 显示全部楼层 |阅读模式

马上注册加入鱼C,享用更多服务吧^_^

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

x
本帖最后由 jerryxjr1220 于 2018-1-16 11:19 编辑

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

1. 楼主不再提供答案。
2. 请大家先独立思考”,再参考其他鱼油的解答,这样才有助于自己编程水平的提高。
3. 鼓励大家积极答题,奖励的期限为出题后24小时内。
4. 根据答案的质量给予1~3鱼币的奖励。

今天的题目是在昨天题目的基础上做了一些改变。
小球从最高处逐层落下,每个节点都有可能向左下或右下方向下落,且几率相同,各占50%,共有10万个小球依次落下,当都从第0层落至第9层时图中0~9的10个位置各有多少个小球(这里为了与python一致,都是从0开始的)。

如果在其中的第5层的中间有一块木板,阻碍了小球的下落,使得到达第5层中间格子的小球只能向两边滚动,向左或向右的概率仍然各50%。求最终落到最底层的9个不同格内的情况,与原来有什么变化。

注:一共应该是10层,下图少画了1层。最下层编号应该是0,1,2,...,9

Untitled.png

本帖被以下淘专辑推荐:

最佳答案
1 
发表于 2018-1-12 10:15:20 | 显示全部楼层
最佳答案
871 
发表于 2018-1-12 10:20:37 | 显示全部楼层
本帖最后由 冬雪雪冬 于 2018-1-12 13:59 编辑

不知是否我的程序有误,感觉没有明显的变化。
原程序我是这样写的:
  1. import random
  2. list1 = [[0 for i in range(j + 1)] for j in range(9)]
  3. list1[0][0] = 100000
  4. for row in range(8):
  5.     for col in  range(row + 1):
  6.         for num in range(list1[row][col]):
  7.             if random.randint(0, 1):
  8.                 list1[row + 1][col] += 1
  9.             else:
  10.                 list1[row + 1][col + 1] += 1
  11. print(list1[8])
复制代码

结果是:[399, 3065, 11024, 21830, 27422, 21762, 10866, 3262, 370]
新的题目我就简单修改了程序:
  1. import random
  2. list1 = [[0 for i in range(j + 1)] for j in range(9)]
  3. list1[0][0] = 100000
  4. for row in range(5):
  5.     for col in  range(row + 1):
  6.         for num in range(list1[row][col]):
  7.             if random.randint(0, 1):
  8.                 list1[row + 1][col] += 1
  9.             else:
  10.                 list1[row + 1][col + 1] += 1

  11. for num in range(list1[4][2]):
  12.     if random.randint(0, 1):
  13.         list1[4][1] += 1
  14.     else:
  15.         list1[4][3] += 1
  16. list1[4][2] = 0

  17. for row in range(5, 8):
  18.     for col in  range(row + 1):
  19.         for num in range(list1[row][col]):
  20.             if random.randint(0, 1):
  21.                 list1[row + 1][col] += 1
  22.             else:
  23.                 list1[row + 1][col + 1] += 1
  24. print(list1[8])
复制代码

结果是:[384, 3145, 10945, 21754, 27203, 21978, 11042, 3153, 396]

============================================
修改成10层后两个程序的结果是:
[201, 1780, 6868, 16311, 24658, 24773, 16449, 7000, 1772, 188]
[219, 1819, 7059, 16349, 24529, 24713, 16407, 7006, 1722, 177]

点评

是我的题目的图片少画了1层,按照9层算,你的应该是对的。  发表于 2018-1-12 11:38
好像你原来的程序的答案也有点错误,你可以去看一下昨天那题大家的解答,基本上都正确的。  发表于 2018-1-12 11:14

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
13 
发表于 2018-1-12 10:36:29 | 显示全部楼层
本帖最后由 shigure_takimi 于 2018-1-15 12:39 编辑
  1. ##  纯计算概率
  2. def f(n):
  3.     if n == 0:
  4.         return [1]
  5.     elif n == 1:
  6.         return [0.5, 0.5] # 1/(2**1)
  7.     elif n > 1:
  8.         a = [1/(2**n),1/(2**n)]
  9.         b = f(n-1)
  10.         for i in range(1, n):
  11.             a.insert(i, (b[i-1]+b[i])/2)
  12.         if n == 4:
  13.             a[1] = a[1] + a[2]/2
  14.             a[3] = a[3] + a[2]/2
  15.             a[2] = 0
  16.         return a


  17. probability = f(9)
  18. for i, p in enumerate(probability):
  19.     print('Position',i,'-->',int(100000*p+0.5))

  20. ##    Position 0 --> 195
  21. ##    Position 1 --> 2344
  22. ##    Position 2 --> 8789
  23. ##    Position 3 --> 16992
  24. ##    Position 4 --> 21680
  25. ##    Position 5 --> 21680
  26. ##    Position 6 --> 16992
  27. ##    Position 7 --> 8789
  28. ##    Position 8 --> 2344
  29. ##    Position 9 --> 195


  30. ##  以下更新于2018-01-15 12:39,随机掉落。
  31. import random
  32. def drop():
  33.     a = [[0 for i in range(10)] for j in range(10)]
  34.     for i in range(10):
  35.         if i == 0:
  36.             index = 0
  37.             a[i][index] = 1
  38.         elif i > 0:
  39.             index = a[i-1].index(1) if random.random() < 0.5 else a[i-1].index(1)+1
  40.             a[i][index] = 1
  41.             if i == 4 and index == 2:
  42.                 a[i][index] = 0
  43.                 index = 1 if random.random()<0.5 else 3
  44.                 a[i][index] = 1
  45.     return a[9].index(1)

  46. result = {}
  47. for i in range(10):
  48.     result[i] = 0

  49. n = 100000
  50. for i in range(n):
  51.     result[drop()] += 1

  52. for k in result:
  53.     print(k, '-->', result[k])


  54. ##    0 --> 192
  55. ##    1 --> 2440
  56. ##    2 --> 8659
  57. ##    3 --> 17024
  58. ##    4 --> 21519
  59. ##    5 --> 21695
  60. ##    6 --> 17093
  61. ##    7 --> 8851
  62. ##    8 --> 2337
  63. ##    9 --> 190
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
jerryxjr1220 + 5 + 5 + 5

查看全部评分

最佳答案
12 
发表于 2018-1-12 10:49:44 | 显示全部楼层
文字描述是10个位置,最终图片是9个位置,以下程序按照图片编写:
import random
print("Let's play a ball game")
ball_num = int(input('ball number:'))
list1=[-1,1]

h1=0
h2=0
h3=0
h4=0
h5=0
h6=0
h7=0
h8=0
h9=0
for x in range(1,ball_num):
        n=0
        for i in range(1,9):
                if i==4 and n==0:
                        n=random.choice((list1*2))
                hole=random.choice(list1)
                n=n+hole
        if n==-8:
                h1+=1
        elif n==-6:
                h2+=1
        elif n==-4:
                h3+=1
        elif n==-2:
                h4+=1
        elif n==-0:
                h5+=1
        elif n==2:
                h6+=1
        elif n==4:
                h7+=1
        elif n==6:
                h8+=1
        elif n==8:
                h9+=1

results=[h1,h2,h3,h4,h5,h6,h7,h8,h9]
print(results)
checkball=sum(results)
print(checkball)

评分

参与人数 1荣誉 +2 鱼币 +2 贡献 +2 收起 理由
jerryxjr1220 + 2 + 2 + 2

查看全部评分

最佳答案
2 
发表于 2018-1-12 10:56:00 | 显示全部楼层
本帖最后由 aegis1417 于 2018-1-12 10:57 编辑

也是類高斯

  1. import random
  2. import matplotlib.pyplot as plt

  3. def num(x):
  4.     c=[]
  5.     y=[]
  6.     count=0
  7.     z=[i for i in range(1,10)]
  8.     for i in range(x):
  9.         a=1
  10.         for j in range(8):
  11.             b=random.randint(0,1)
  12.             a=a+b
  13.             if j==3 and a==3 :
  14.                 count=count+1
  15.                 b=random.sample([1,-1], 1)
  16.                 a=a+b[0]      
  17.         c.append(a)
  18.     for x in range(1,10):
  19.         y.append(c.count(x))
  20.     print(z,y)
  21.     print('撞到板子%d次' %count)
  22.     plt.plot(z, y)
  23.     plt.show()

  24. num(100000)
复制代码


[1, 2, 3, 4, 5, 6, 7, 8, 9] [400, 4368, 13316, 20665, 22512, 20838, 13279, 4259, 363]
撞到板子37651次
every138.jpg

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
18 
发表于 2018-1-12 13:10:15 | 显示全部楼层
  1. import random

  2. def put_one_ball_to_5():
  3.     return [True if random.randint(0,1) else False for i in range(4)].count(True)

  4. def put_one_ball():
  5.     n = put_one_ball_to_5()
  6.     if n == 2:
  7.         if random.randint(0,1):
  8.             n = n + 1
  9.         else:
  10.             n = n - 1
  11.     return n + put_one_ball_to_5() + random.randint(0,1)

  12. def put_balls(num):
  13.     return [put_one_ball() for i in range(num)]

  14. balls = put_balls(100000)
  15. for i in range(10):
  16.     print(i,balls.count(i))
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
0 
发表于 2018-1-12 13:40:53 | 显示全部楼层
  1. import random
  2. layer_list = [ ]
  3. for i in range(1,9):
  4.         temp = list(range(1,i+2))
  5.         layer_list.append(temp)
  6. print(layer_list)

  7. num = list(range(1,10))
  8. out = [0] * 9
  9. for x in range(0,100000):
  10.         layer = []          #一个小球落下的结果
  11.         layer.append(random.randint(1,2))
  12.         for i in range(0,7) :
  13.                 if (i == 3) and layer[i] == 3:                      #改进
  14.                         layer[i]= random.randrange(2,5,2)
  15.                         layer.append(random.randint(layer[i],layer[i]+1))
  16.                         continue
  17.                 for j in range(0,i+2):
  18.                         if layer[i] == layer_list[i][j]:
  19.                                 layer.append(random.randint(layer_list[i][j],layer_list[i][j]+1))
  20.         for y in range(0,9):      #计数
  21.                 if layer[7] == num[y]:
  22.                         out[y] += 1
  23. print(out)
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
2 
发表于 2018-1-12 19:15:15 | 显示全部楼层
mark一下。。。。。
最佳答案
5 
发表于 2018-1-12 20:46:06 | 显示全部楼层
仍然是9次伯努利试验,将第4次的结果中间值2平分到左右1和3去
分布上看均值μ不变,标准差增大了,反映到图上就是线扁平了
  1. import matplotlib.pyplot as plt
  2. import numpy as np

  3. def fun(n=100000):
  4.     a = np.add.reduce(np.random.randint(0, 2, (4, n)), 0)
  5.     a = np.where(a==2, a+np.random.choice([-1,1], (n,)), a)
  6.     b = np.add.reduce(np.random.randint(0, 2, (5, n)), 0)
  7.    
  8.     plt.hist(a+b, 10, range=(-0.5, 9.5))
  9.     plt.xticks(np.arange(-1, 10, 1))
  10.     plt.show()
复制代码

对比样本数据,图变扁平了
昨天的[   207.   1758.   6997.  16134.  24549.  25017.  16343.   7041.   1776. 178.]
今天的[   199.   2324.   8866.  16991.  21497.  21612.  17097.   8880.   2337. 197.]
figure_2.png

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
jerryxjr1220 + 5 + 5 + 5

查看全部评分

最佳答案
1 
发表于 2018-1-12 22:38:44 | 显示全部楼层
  1. from random import choice
  2. from time import perf_counter

  3. def random_drop(n):
  4.     tiers = []
  5.     for i in range(10):
  6.         tiers.append([0 for j in range(i + 1)])
  7.     tiers[0][0] = n
  8.     for i in range(9):
  9.         if i != 4:
  10.             for j in range(len(tiers[i])):
  11.                 if tiers[i][j]:
  12.                     for k in range(tiers[i][j]):
  13.                         tiers[i+1][choice([j, j+1])] += 1
  14.         else:

  15.             for j in range(tiers[i][2]):
  16.                 direction = choice([-1, 1])
  17.                 tiers[i][2+direction] += 1


  18.             for j in range(len(tiers[i])):
  19.                 if i != 2 and tiers[i][j]:
  20.                     for k in range(tiers[i][j]):
  21.                         tiers[i+1][choice([j, j+1])] += 1
  22.     return tiers[-1]


  23. if __name__ == '__main__':
  24.     start = perf_counter()
  25.     print(random_drop(100000))
  26.     stop = perf_counter()
  27.     print("time used:%f s" %(stop - start))
复制代码

结果:[208, 2352, 10018, 22722, 33467, 33293, 22959, 9998, 2319, 194]

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
20 
发表于 2018-1-12 23:22:59 | 显示全部楼层
  1. import random as r

  2. # 定义左右滚动的点, 目前不能是边界点, 其余为从上到下的运动点
  3. tmp = [(4,2)]


  4. # 定义一个球从i层的第n个位置到下一层的随机选择
  5. def fun(i, n):
  6.     if (i,n) in tmp:
  7.         # print("done")
  8.         # print(i,n)
  9.         n += r.choice([-1,1])
  10.         # print(i,n)
  11.     else:
  12.         i += 1
  13.         n += r.choice([0,1])
  14.     return i, n


  15. # 定义一个球从最顶端到最低端的选择
  16. def one_loop(n) :
  17.     now = (0,0)
  18.     while now[0] < n-1:
  19.         now = fun(now[0],now[1])
  20.     return now[1]

  21. # 定义count个球从最顶端到最低端floor层的选择
  22. def loop(floor, count):   
  23.     mdict = {}.fromkeys(range(floor), 0)

  24.     for i in range( count ):
  25.         mdict[ one_loop(floor) ] += 1
  26.         
  27.     return mdict

  28. # 主函数测试
  29. def main():
  30.     floor = 10
  31.     count = 100000

  32.     mdict = loop(floor, count)

  33.     for key in mdict:
  34.         print(key, mdict[key])

  35.     print("result: ", sum(mdict.values()) == count)
  36.         

  37. if __name__ == "__main__":
  38.     main()
复制代码


结果:
  1. 0 186
  2. 1 2349
  3. 2 8622
  4. 3 16819
  5. 4 21892
  6. 5 21464
  7. 6 17149
  8. 7 8939
  9. 8 2396
  10. 9 184
  11. result:  True
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
1 
发表于 2018-1-13 18:03:46 | 显示全部楼层
  1. import random
  2. import time


  3. def zero_or_one():
  4.     if random.random() < 0.5:
  5.         t = 0
  6.     else:
  7.         t = 1
  8.     yield t


  9. # 最终位置: 往左不变, 往右加 1
  10. def get_str(num_of_sphere=10, r=10):
  11.     while num_of_sphere:
  12.         final_position = 0
  13.         for i in range(r - 1):
  14.             direction = next(zero_or_one())
  15.             if direction:
  16.                 final_position += 1
  17.         num_of_sphere -= 1
  18.         yield final_position


  19. total = 100000
  20. row = 10
  21. print('试验总球数为: {}'.format(total))
  22. t_list = list(get_str(total, row))
  23. starttime = time.time()
  24. for num in range(row):
  25.     print('落在第 {} 个位置的球个数为: {}'.format(num, t_list.count(num)))
  26. print(time.time() - starttime)
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
jerryxjr1220 + 3 + 3 + 3

查看全部评分

最佳答案
1 
发表于 2018-1-13 18:04:28 | 显示全部楼层

朋友教我的 不算  
最佳答案
0 
发表于 2018-1-15 13:41:04 | 显示全部楼层
  1. import random as r
  2. count=0   
  3. i=0
  4. num=0
  5. i=0
  6. list1=[0,1,2,3,4,5,6,7,8,9]
  7. list2=[0,0,0,0,0,0,0,0,0,0]

  8. while count < 100000:
  9.     n=0
  10.     i=0
  11.     while i <10:
  12.         
  13.         if i ==5 and n==2:
  14.             n = r.randrange(1,3,2)
  15.             i=4
  16.             
  17.         else:
  18.             if i==0:
  19.                 n=0
  20.             else:
  21.                 n=r.randint(n,n+1)
  22.         
  23.         
  24.         i =i+1
  25.         
  26.         
  27.         
  28.     count=count+1
  29.     list2[n]=list2[n]+1
  30.    
  31.    
  32.    
  33. print(list2)

  34.    




复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 贡献 +2 收起 理由
jerryxjr1220 + 2 + 2 + 2

查看全部评分

最佳答案
1 
发表于 2018-1-16 14:09:04 | 显示全部楼层
  1. import random
  2. result = []
  3. for i in range(10):
  4.     result.insert(i,0)
  5. t=0
  6. while t<100000:
  7.     ball = 0
  8.     for i in range(9):
  9.         if i == 3 and ball == 2:
  10.             ball += random.choice([-1,1])
  11.         ball += random.choice([0,1])
  12.     result[ball] += 1
  13.     t += 1
  14. print(result)
复制代码
最佳答案
1 
发表于 2018-2-8 21:28:14 | 显示全部楼层

运行10次的结果

本帖最后由 kwty 于 2018-2-8 21:29 编辑
  1. import random as rd
  2. import matplotlib.pyplot as plt
  3. def f():
  4.         c = 0
  5.         L = [-1, 1]
  6.         for i in range(9):
  7.                 while i == 4 and c == 2:
  8.                         c += L[rd.randint(0, 1)]
  9.                         break
  10.                 c += rd.randint(0,1)
  11.         return c
  12. for k in range(10):
  13.         l = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  14.         for i in range(100000):
  15.                 l[f()] += 1

  16.         print(l)
  17. '''x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  18. plt.scatter(x,l)
  19. plt.show()'''


  20. [177, 2292, 8874, 17070, 21758, 21675, 16955, 8709, 2306, 184]
  21. [202, 2306, 8650, 16957, 21670, 21704, 17003, 8905, 2402, 201]
  22. [204, 2377, 8825, 16826, 21593, 21535, 17253, 8817, 2377, 193]
  23. [180, 2413, 8835, 16949, 21418, 21877, 17035, 8755, 2343, 195]
  24. [186, 2379, 9028, 17024, 21765, 21692, 16772, 8586, 2375, 193]
  25. [183, 2369, 8691, 16922, 21525, 21704, 17134, 8914, 2346, 212]
  26. [201, 2250, 8710, 16827, 21742, 21660, 17066, 8912, 2456, 176]
  27. [195, 2340, 8747, 16918, 21765, 21391, 17203, 8883, 2333, 225]
  28. [189, 2359, 8865, 17061, 21874, 21641, 16829, 8669, 2314, 199]
  29. [203, 2448, 8736, 16993, 21633, 21700, 17012, 8700, 2374, 201]
复制代码
最佳答案
0 
发表于 2018-5-7 13:20:44 | 显示全部楼层
抄了楼主137题的代码,在第五层时加了判断的条件,
import matplotlib.pyplot as plt
class balls:
    def __init__(self):
        self.matrix = [[0]*i for i in range(1, 11)]
        self.matrix[0][0] = 1
    def roll(self, row, col):
        if row >= 9: return
        import random
        if random.random() >= 0.5:
            if row == 4 and col == 2:
                self.matrix[row][col+1] = 1
                self.roll(row, col+1)
            else:
                self.matrix[row+1][col+1] = 1
        else:
            if row == 4 and col == 2:
                self.matrix[row][col-1] = 1
                self.roll(row, col-1)
            else:
                self.matrix[row+1][col] = 1
        self.matrix[row][col] = 0
    def start(self):
        for r in range(10):
            for c in range(r+1):
                if self.matrix[r][c] == 1:
                    self.roll(r, c)
                    break
        return sum(k*v for k, v in enumerate(self.matrix[9]))
result = [0]*10
for repeat in range(100000):
    test = balls()
    result[test.start()] += 1
print(result)
num = [i for i in range(10)]
plt.plot(num, result)
plt.show()
[174, 2341, 8740, 16930, 21665, 21689, 17065, 8800, 2396, 200]
137题的对比
[177, 1791, 7045, 16338, 24552, 24716, 16593, 6845, 1761, 182]
最佳答案
6 
发表于 2018-5-7 17:14:58 | 显示全部楼层
  1. import random

  2. #n表示小球的位置, m表示小球所在层数
  3. def game(n = 0, m = 0):
  4.     n =n + random.randint(0, 1)
  5.     if m == 8:
  6.         return n
  7.     else:
  8.         return game(n, m + 1)

  9. def game2(n = 0, m = 0):
  10.     if m == 4:
  11.         if n == 2:
  12.             if random.randint(0, 1):
  13.                 n += 1
  14.             else:
  15.                 n -= 1
  16.             return game(n, m)
  17.     n += random.randint(0, 1)
  18.     if m == 8:
  19.         return n
  20.     return game2(n, m + 1)


  21. x = []
  22. y = []
  23. for i in range(0, 10):
  24.     x.append(0)
  25.     y.append(0)
  26. for i in range(100001):
  27.     x[game()] += 1
  28.     y[game2()] += 1
  29. for i in range(10):
  30.     print('位置%d有%d个球\t' %(i, x[i]), end = '')
  31.     print('位置%d有%d个球' %(i, y[i]))
复制代码
最佳答案
6 
发表于 2018-5-7 18:52:05 | 显示全部楼层
位置0有203个球          位置0有218个球
位置1有1753个球         位置1有2324个球
位置2有7179个球         位置2有8797个球
位置3有16324个球        位置3有16927个球
位置4有24535个球        位置4有21458个球
位置5有24651个球        位置5有21576个球
位置6有16320个球        位置6有17193个球
位置7有7038个球         位置7有8917个球
位置8有1794个球         位置8有2414个球
位置9有204个球          位置9有177个球
我的答案是这样的
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

小甲鱼强烈推荐上一条 /1 下一条

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号 )

GMT+8, 2018-7-23 21:25

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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