向人们介绍离散概率分布概念的一个典型例子是豆机。这台机器有大量的弹珠从顶部一条狭窄的通道上掉下来,之后,它们撞上了一排排交错的引脚,在每一根针上,大理石都可能落在针的左边或右边。最后,将引脚收集到机器底部的垂直回收箱中。这台机器的简单图表如下所示:
| O |
| ^ |
| ^ ^ |
| ^ ^ ^ |
| ^ ^ ^ ^ |
| ^ ^ ^ ^ ^ |
|_|_|_|_|_|_|在这个图表中,O表示弹珠下落的位置。每个^是一个引脚,大理石有50%的机会移动到正方形,无论是左边还是右边的别针。然后,弹珠聚集在设备底部的垃圾箱中,对于足够多的大理石,回收箱中大理石堆的高度将类似于一个离散的二项分布。
对于这一挑战,您将根据上面的图表计算bean机器的最终概率分布。这些图表被解释为一个二维的“程序”,弹珠通过这个程序,要么指向边的字段,要么指向当前场下的字段。当弹珠到达机器底部时,它们被计算为概率分布。为了保持它的趣味性,这些图表将包含更多的字段,而不仅仅是简单的源和引脚。一个示例图是:
| O |
| ^ |
| ^ / |
| ^ | ^ |
| <^- = v |
| ^ ^ ^ ^ ^ |此外,弹珠现在每个都有一个旋转方向。这个方向由一些字段设置,并确定大理石在其他几个字段中移动到哪个字段。
定义了以下字段:
O:来源。在它的正下方产生弹珠。这些弹珠的方向是左50%,右50%。每个来源生产相同数量的弹珠。U:水槽。进入此字段的任何弹珠都会从bean机器中移除。-:地板。如果一个大理石到达这个领域,它将移动到左边的字段或右边的字段,这取决于其当前的方向。^:分离器。如果一个大理石到达这个领域,它有50%的移动到能量场的右边,或者能量场的左边。这也决定了大理石的方向。v:加入。如果一个大理石到达这个领域,它将移动到下面的田野。/:倾斜垫。如果一个大理石到达这个领域,它将移动到球场的左边的垫,设置大理石的方向。\:和以前的一样,但在右边。|:反射器。如果一个大理石到达这个领域,它将反转大理石的方向,并根据这个相反的方向将大理石移动到右边或左侧。=:大炮。如果一个大理石到达这个领域,它将向右或向左移动,直到大理石遇到一个不是-或O的字段。<:与前一个相同,但总是会设置方向并向左移动。>:和以前的一样,但在右边。对图表提供了以下保证。
|。\/或^^。您的任务将是生成一个16行高的ASCII条形图的概率分布,其中弹珠退出图形的底部,因此最大的概率涵盖所有16个字符。因此,对于以下问题:
| O |
| ^ |
| ^ ^ |
| ^ ^ ^ |
| ^ ^ ^ ^ |
| ^ ^ ^ ^ ^ |您的程序应该产生以下解决方案(注意,它应该具有与输入程序相同的宽度,包括侧的管道):
# #
# #
# #
# #
# #
# #
# #
# #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # # # #
# # # # # # 下面是一个应该测试所有不同字段类型的功能的示例:
| O O |
| O ^ / <^\\\ |
| ^ > ^ |
| ^ ^ ^ =|
| ^ ^ | ^ <^ O |
| ^ > ^ | ^ O ^> v |
|| ^U ^ | = ^\ |
| ^ ^ ^ ^U ^\ ---^ |
| = ^ ^ = v |它应产生以下输出:
#
#
#
#
# #
# #
# #
# # # #
# # # #
# # # #
# # # #
## # # #
## # # # #
# ### # # # #
# # ### # # # #
# # ### # # # # 功能和完整的程序构成了这一挑战的有效答案。您将收到图作为换行符分隔的字符串,并且应该以给定的格式返回输出图。默认输入/输出规则应用。虽然输出中允许尾随和前导换行符,但每一行的宽度都应与输入完全相同。
为了允许更有创造性的解决方案,只需要您的程序输出相同图表90%以上的正确结果。毕竟,这是一个概率模拟。
这是密码-高尔夫,所以以字节为单位的最低分数获胜。
发布于 2017-06-29 04:38:00
i=raw_input
l=i()
c=[]
while l:c,l=c+[l],i()
p=[[0]*len(l)for l in c]+[[0]*max(map(len,c))]
S=lambda r,C,p:r>=0and C>=0and r<len(p)and C<len(p[r])
def U(r,C,P,D,N=0):
if S(r,C,p):p[r][C]+=P
if S(r,C,c):
K=c[r][C]
if K in' O':U(r+1-N,C+D*N,P,D,N)
elif'v'==K:U(r+1,C,P,D)
elif'-'==K:U(r,C+D,P,D,N)
elif'^'==K:U(r,C-1,P/2,-1);U(r,C+1,P/2,1)
elif'/'==K:U(r,C-1,P,-1)
elif'\\'==K:U(r,C+1,P,1)
elif'='==K:U(r,C+D,P,D,1)
elif'>'==K:U(r,C+1,P,1,1)
elif'<'==K:U(r,C-1,P,-1,1)
elif'|'==K:U(r,C-D,P,-D)
for r in range(len(c)):
for C in range(len(c[r])):
if'O'==c[r][C]:U(r+1,C,1.,1);U(r+1,C,1.,-1)
p=p[-1][::-1]
s=16/max(p)
f=['#'*min(int(n*s),16)+' '*min(int(16-n*s),16)for n in p]
print('\n'.join(map(''.join,zip(*f)))[::-1])-17字节,多亏了凯恩斯的共同继承
-12字节,感谢内森·希莱里
-56字节,切换到混合缩进(Python 2)
-28多亏了CensoredUsername,因为最终的概率是规范化的,所以没有必要将最终概率加为1。
-7字节,这要归功于计算器Feline,它使用了一个较短的结束elif语句。
-将两个函数合并为218个字节
https://codegolf.stackexchange.com/questions/128851
复制相似问题