鱼C论坛

 找回密码
 立即注册
查看: 2799|回复: 17

[技术交流] 鱼C论坛python精英挑战赛(05期)评选结果

[复制链接]
发表于 2017-7-7 09:41:09 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 jerryxjr1220 于 2017-7-7 13:11 编辑

本次挑战赛参赛人员共三位:WelanceLee,lovesword,小锟

由于本次的题目是开放性命题,没有绝对正确的答案,只需要程序合理,能自圆其说就算正确。

按照评选规则,从合理性,效率,创意和简洁方面进行了评比。

无标题.png

综合评分WelanceLee胜出,他使用手动的方法实现了机器学习,程序简洁,效率高,对于想要学习机器学习原理的同学有很大的借鉴价值。

同时,小锟的程序直接调用了机器学习库,并通过调整参数优化了程序,也是非常不错的解法。

所以,我决定额外奖励100鱼币给小锟同学,请去补充奖励帖领奖。

本帖被以下淘专辑推荐:

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

使用道具 举报

 楼主| 发表于 2017-7-7 10:02:46 | 显示全部楼层
本届鱼C论坛python精英挑战赛的5场比赛全部结束,感谢大家的参与!

最后的最后,留道思考题吧。

筛子点数的概率:
请设计一个函数dice(number_of_dices, sides_of_dice, target)输出掷出某个点数的概率。
其中,number_of_dices表示筛子个数, sides_of_dice表示筛子的面数, target表示目标点数。
假定所有的骰子是相同的,并且从1到N编号。因此,四面模具(D4)将具有相同的滚动1,2,3或4的机会。
如果无法掷出目标点数,则返回0.
取值范围:
1 ≤ number_of_dices ≤ 10
2 ≤  sides_of_dice ≤ 20
0 ≤ target < 1000

测试值:
dice(2, 6, 3) == 0.0556  # 2 six-sided dice have a 5.56% chance of totalling 3
dice(2, 6, 4) == 0.0833
dice(2, 6, 7) == 0.1667
dice(2, 3, 5) == 0.2222  # 2 three-sided dice have a 22.22% chance of totalling 5
dice(2, 3, 7) == 0       # The maximum you can roll on 2 three-sided dice is 6
dice(3, 6, 7) == 0.0694
dice(10, 10, 50) == 0.0375
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-7 13:12:01 | 显示全部楼层
回答思考题同样有奖励哦!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-7 14:54:25 | 显示全部楼层

回帖奖励 +10 鱼币

  1. def dice(n, m, y):
  2.     if n*m < y or n > y:
  3.         return 0
  4.     if n == 1:
  5.         if 0 < y <= m:
  6.             return 1/m
  7.         else:
  8.             return 0
  9.     s = 0
  10.     for i in range(1, m+1):
  11.         s += 1/m*dice(n-1, m, y-i)
  12.     return s
复制代码

速度很一般,但结果应该是对滴!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-7 16:22:24 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-7-7 16:24 编辑
WelanceLee 发表于 2017-7-7 14:54
速度很一般,但结果应该是对滴!


嗯,估计那个(10,10,50)的你这个程序跑不出来。

不过你可以考虑,做个数组,把所有计算过的n, m, y记录下来,这样就不会陷入循环递归了,速度应该可以快很多。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-12 21:25:40 | 显示全部楼层

回帖奖励 +10 鱼币

能不能发下你的代码,我用深度优先遍历不知道如何返回每一条路径,用itertools的笛卡尔积做又太慢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-12 21:59:29 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-7-12 22:09 编辑
小锟 发表于 2017-7-12 21:25
能不能发下你的代码,我用深度优先遍历不知道如何返回每一条路径,用itertools的笛卡尔积做又太慢了{:5_92: ...


你可以用numba神器加速啊

活用functools也是神器,见楼下解答。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-12 22:08:49 | 显示全部楼层
WelanceLee 发表于 2017-7-7 14:54
速度很一般,但结果应该是对滴!

帮你的程序做了下改进,用了functools神器,瞬间你的程序性能就提升了。
  1. from functools import lru_cache
  2. @lru_cache(maxsize=None)
  3. def dice(n, m, y):
  4.     if n*m < y or n > y:
  5.         return 0
  6.     if n == 1:
  7.         if 0 < y <= m:
  8.             return 1/m
  9.         else:
  10.             return 0
  11.     s = 0
  12.     for i in range(1, m+1):
  13.         s += 1/m*dice(n-1, m, y-i)
  14.     return s

  15. print(dice(10,10,50))
复制代码

秒出答案
0.03748943890000003
[Finished in 0.1s]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 00:26:49 | 显示全部楼层
  1. def dice(num ,sides ,target):
  2.     import itertools as it
  3.     a = it.product(*[range(1,sides + 1)] * num)
  4.     result = sorted(list(map(sum,list(a))))
  5.     length = len(result)
  6.     try:
  7.         index = result.index(target)
  8.         index2 = result[::-1].index(target)
  9.         numbers = length - index - index2           
  10.     except ValueError:
  11.         numbers = 0
  12.     return numbers / length
复制代码

来试试我这个,哈哈哈,我的破电脑内存瞬间不够了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 06:51:33 | 显示全部楼层

回帖奖励 +10 鱼币

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

使用道具 举报

发表于 2017-7-13 10:04:43 | 显示全部楼层
jerryxjr1220 发表于 2017-7-12 22:08
帮你的程序做了下改进,用了functools神器,瞬间你的程序性能就提升了。

秒出答案
  1. d = ['0','1','2','3','4','5','6','7','8','9']
  2. def gfs(s, n):
  3.     if len(s) == n:
  4.         print(s)
  5.         yield s
  6.     for each in d:
  7.         s += each
  8.         gfs(s, n)
  9.         s = s[:-1]
复制代码

有个问题想请教下,我想做一个生成器,生成n为数字允许重复的排列组合,但是我这样的程序没有作用,yield到底放在哪才能有效?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-13 11:13:25 From FishC Mobile | 显示全部楼层
WelanceLee 发表于 2017-7-13 10:04
有个问题想请教下,我想做一个生成器,生成n为数字允许重复的排列组合,但是我这样的程序没有作用,yie ...

没有理解你的意思,一般来说直接用yield替换return就能改写成生成器。不同点是用了return程序就终止了,而用yield的话,程序会继续运行直到遇到下一个yield,然后程序就等着下次调用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 11:31:13 | 显示全部楼层
jerryxjr1220 发表于 2017-7-13 11:13
没有理解你的意思,一般来说直接用yield替换return就能改写成生成器。不同点是用了return程序就终止了, ...

应该是n位,我写错了,就是我把程序中的yield改成return,比如运行gfs('',2),会产生(00,01,02……99),但是我把改成yield就没有任何结果~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 12:47:16 | 显示全部楼层
WelanceLee 发表于 2017-7-13 11:31
应该是n位,我写错了,就是我把程序中的yield改成return,比如运行gfs('',2),会产生(00,01,02……99 ...

这个函数如果把print(s)去掉然后把yield变成return,会发现他返回的是None,这种事我也遇到过,具体百度。。。。。。。Python递归返回的是none。。。。。。。但是找到问题后你会发现还要运行return  gfs(s, n)
后面的一句s = s[:-1] 但是return后就跳过后面这句了,我也很苦恼啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 14:59:27 | 显示全部楼层

回帖奖励 +10 鱼币

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

使用道具 举报

 楼主| 发表于 2017-7-13 21:56:16 | 显示全部楼层
WelanceLee 发表于 2017-7-13 11:31
应该是n位,我写错了,就是我把程序中的yield改成return,比如运行gfs('',2),会产生(00,01,02……99 ...

那这不就是itertools.product函数吗?你去看下源码不就好了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-4 20:34:43 | 显示全部楼层
双击评论‘666’
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-4 20:35:23 | 显示全部楼层

回帖奖励 +10 鱼币

双击评论‘666’
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 15:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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