首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一台瘦削的、刻薄的豆机

一台瘦削的、刻薄的豆机
EN

Code Golf用户
提问于 2017-06-28 13:58:37
回答 1查看 665关注 0票数 26

向人们介绍离散概率分布概念的一个典型例子是豆机。这台机器有大量的弹珠从顶部一条狭窄的通道上掉下来,之后,它们撞上了一排排交错的引脚,在每一根针上,大理石都可能落在针的左边或右边。最后,将引脚收集到机器底部的垂直回收箱中。这台机器的简单图表如下所示:

代码语言:javascript
复制
|     O     |
|     ^     |
|    ^ ^    |
|   ^ ^ ^   |
|  ^ ^ ^ ^  |
| ^ ^ ^ ^ ^ |
|_|_|_|_|_|_|

在这个图表中,O表示弹珠下落的位置。每个^是一个引脚,大理石有50%的机会移动到正方形,无论是左边还是右边的别针。然后,弹珠聚集在设备底部的垃圾箱中,对于足够多的大理石,回收箱中大理石堆的高度将类似于一个离散的二项分布。

挑战

对于这一挑战,您将根据上面的图表计算bean机器的最终概率分布。这些图表被解释为一个二维的“程序”,弹珠通过这个程序,要么指向边的字段,要么指向当前场下的字段。当弹珠到达机器底部时,它们被计算为概率分布。为了保持它的趣味性,这些图表将包含更多的字段,而不仅仅是简单的源和引脚。一个示例图是:

代码语言:javascript
复制
|     O     |
|     ^     |
|    ^ /    |
|   ^ | ^   |
|  <^- =  v |
| ^ ^ ^ ^ ^ |

此外,弹珠现在每个都有一个旋转方向。这个方向由一些字段设置,并确定大理石在其他几个字段中移动到哪个字段。

定义了以下字段:

  • O:来源。在它的正下方产生弹珠。这些弹珠的方向是左50%,右50%。每个来源生产相同数量的弹珠。
  • U:水槽。进入此字段的任何弹珠都会从bean机器中移除。
  • ::空位。如果一个大理石到达这个领域,它将移动到下面的田野。
  • -:地板。如果一个大理石到达这个领域,它将移动到左边的字段或右边的字段,这取决于其当前的方向。
  • ^:分离器。如果一个大理石到达这个领域,它有50%的移动到能量场的右边,或者能量场的左边。这也决定了大理石的方向。
  • v:加入。如果一个大理石到达这个领域,它将移动到下面的田野。
  • /:倾斜垫。如果一个大理石到达这个领域,它将移动到球场的左边的垫,设置大理石的方向。
  • \:和以前的一样,但在右边。
  • |:反射器。如果一个大理石到达这个领域,它将反转大理石的方向,并根据这个相反的方向将大理石移动到右边或左侧。
  • =:大炮。如果一个大理石到达这个领域,它将向右或向左移动,直到大理石遇到一个不是-O的字段。
  • <:与前一个相同,但总是会设置方向并向左移动。
  • >:和以前的一样,但在右边。

对图表提供了以下保证。

  • 每个输入行在字段中具有完全相同的长度。
  • 每行的最左边和最右边的字段总是一个|
  • 该图表将不包含任何可能的路径,通过这些路径,大理石就可以卡在机器中进行不确定的迭代,比如\/^^
  • 图表将只包含上述字段。
  • 有一个或多个来源

结果

您的任务将是生成一个16行高的ASCII条形图的概率分布,其中弹珠退出图形的底部,因此最大的概率涵盖所有16个字符。因此,对于以下问题:

代码语言:javascript
复制
|     O     |
|     ^     |
|    ^ ^    |
|   ^ ^ ^   |
|  ^ ^ ^ ^  |
| ^ ^ ^ ^ ^ |

您的程序应该产生以下解决方案(注意,它应该具有与输入程序相同的宽度,包括侧的管道):

代码语言:javascript
复制
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
   # # # #  
   # # # #  
   # # # #  
   # # # #  
   # # # #  
   # # # #  
 # # # # # #
 # # # # # # 

示例

下面是一个应该测试所有不同字段类型的功能的示例:

代码语言:javascript
复制
|     O     O         |
|  O  ^ /  <^\\\      |
|    ^ >            ^ |
|   ^ ^ ^            =|
|  ^ ^ | ^    <^   O  |
| ^ > ^ | ^   O ^> v  |
||  ^U  ^  |  =    ^\ |
|  ^ ^ ^ ^U ^\ ---^   |
| = ^   ^     =    v  |

它应产生以下输出:

代码语言:javascript
复制
                     # 
                     # 
                     # 
                     # 
                   # # 
                   # # 
                   # # 
       # #         # # 
       # #         # # 
       # #         # # 
       # #         # # 
      ## #         # # 
      ## # #       # # 
   # ### # #       # # 
 # # ### # #       # # 
 # # ### # #       # # 

规则

功能和完整的程序构成了这一挑战的有效答案。您将收到图作为换行符分隔的字符串,并且应该以给定的格式返回输出图。默认输入/输出规则应用。虽然输出中允许尾随和前导换行符,但每一行的宽度都应与输入完全相同。

为了允许更有创造性的解决方案,只需要您的程序输出相同图表90%以上的正确结果。毕竟,这是一个概率模拟。

评分

这是密码-高尔夫,所以以字节为单位的最低分数获胜。

EN

回答 1

Code Golf用户

发布于 2017-06-29 04:38:00

Python 2,731字节

代码语言:javascript
复制
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个字节

票数 4
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/128851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档