简单的红石模拟器


27

Redstone是Minecraft游戏中的一种材料,可用于许多复杂的装置。对于此程序,您只需模拟三个项目:红石线(用R表示),红石火炬(用T表示)和块(用B表示)。

以下是有关红石原理的基本规则列表:

A redstone torch sends power to any adjacent redstone wire.
TRRRR
 ^This redstone wire is powered.

Redstone wire can only hold power for 15 blocks.
TRRRRRRRRRRRRRRRR
                ^This last wire is unpowered, because the torch is >15 blocks away.

A block is said to be powered if a powered redstone wire is found adjacent to it.
TRRRB
    ^This block is powered.

If a block next to a redstone torch is powered, then the torch stops emitting power.
T
R
R
R
B <This block is powered.
T <This redstone torch does not emit power because of the block next to it.
R <This redstone is unpowered because the torch is not providing power.
R

输入将以不超过64x64的二维数组形式给出,如下所示:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

可以确保输入没有任何“时钟”,也不会由火炬驱动的红石指向火炬打开的块。每个输入只有一个红石电路。

您的程序必须将每个字符更改为1或0,表示此项目是带电/不通电的1,如果不带电/不通电则为0。

此输入应具有以下输出:

1111
   1
100000
1
111111111
        1
   001111

这是一个代码高尔夫,因此一如既往地赢得了最短的代码。


1
在类似情况下,您希望获得什么输出"TRR\nB B\nRRT"
霍华德

111\n0 1\n000是输出;似乎在规则之内。我将设置输入限制,说您不能有类似的情况TRR B R RRR反复闪烁。
beary605

1
我们是否可以像您的示例那样假设每个输入阵列仅包含一个从上到下运行的完整电路,还是我们必须为从阵列中任何位置开始的多个独立电路编写代码?
格雷厄姆

@格雷厄姆:每个输入只有一个红石电路。
beary605

1
知道了《我的世界》游戏后,我认为在您的示例中,鉴于第2行上的方块,并不能阻止相邻的割炬通电(红石实际上并未连接到方块)。这是错误还是简化?
tomsmeding

Answers:


4

哈斯克尔(400)

import Data.Char
import Data.List
f x=[(++[x]).tail,(x:).init]
h(' ':_)=' '
h('T':s)=if elem 'b's then 'T'else 't'
h('t':s)=h$'T':s
h('B':s)=if any(`elem`s)['e'..'s']then 'b'else 'B'
h('b':s)=h$'B':s
h(_:s)=max 'd'$chr$ord(maximum s)-1
o ' '=' '
o c|elem c"dTB"='0'
o _='1'
a=(map.map)o.(!!(64^2+16)).iterate(map(map h.transpose).transpose.(\l->[g l|g<-id:f(map(const ' ')$head l)++map map (f ' ')]))

map(map h.transpose).transpose.(\l->[g l|g<-id:f(map(const ' ')$head l)++map map (f ' ')])将每个图块替换为其自身列表,后跟四个邻居,然后通过h进行映射。h表示每个瓦片对邻居的反应:当附近有电源块(b)时,割炬关闭('T'而不是't'),导线('d'表示通过's'的死线)的复制不完美他们最有能力的邻居(虽然不能变得比死者还糟),等等。

iterate重复此步骤,(!!(64^2+16))进行一次迭代,完成非循环电路的收敛,我完全这样写,以给出一个直观的界限,而不是降到400。


4

Python,699

这只是一个快速通过(暂时没有时间)。它可能会使用更多的高尔夫球。

import sys
m=[list(x)for x in sys.stdin.read().split('\n')]
e=enumerate
S=set
s=lambda x:S([(r,c)for r,i in e(m)for c,j in e(i)if j==x])
q=S()
t=s('T')
b=s('B')
n=s('R')
def d(o,r,c,i,h,q):
 if i<0:return 0
 o[(r,c)]=1
 for p in[(r+1,c),(r-1,c),(r,c+1),(r,c-1)]:
  if p in q or(p in b and not(r,c)in n):continue
  if(r,c)in b and p in t-q:
   x=S([p])
   q|=x
   o[p]=0
   return 1
  if p in h or not p in o:continue
  h|=S([p])
  if not d(o,p[0],p[1],i-1,h,q):return 1
g=1
while g:
 o=dict(zip(b,[0]*len(b))+zip(n,[0]*len(n))+zip(q,[0]*len(q)))
 g=0
 for x,y in t:
  if not(x,y)in q and d(o,x,y,15,S(),q):g=1
for p in o.keys():m[p[0]][p[1]]=o[p]
print"\n".join(map(lambda x:"".join(map(str,x)),m))

是的,例如,您可以使用f=set并创建一个l=lambda x:zip(x,[0]*len(x))。好吧,您仍然会超过700个字符。另外,您还在留下了无用的空间... or not (a,z)in o
Morwenn

打印声明后是否需要空格?
扎卡里

@ZacharyT你是对的。谢谢!
ESultanik '17

这是已经说过,但f=set会剃了几个字符,你有另一种无用的角色@not (a,z)in o
扎卡里

使用制表符和空格可以节省一些缩进。
mbomb007 '17

4

Python 2,556字节

c=' 0';L=len;M=map;q=list;r='B';s='16';t='T';u='0';E=enumerate
b=[q(M(lambda x:x+[u,s][x==t],q(w[:-1])))+[c]*(64-L(w))for w in open('redstone.txt')]
k=lambda h,l,z:max(q(M(lambda x:[int((x or c)[1:]),0][l^((x or c)[0]==h)],z)))
def v(d=0):
 for e,f in E(b):
    for g,G in E(f):z=[e!=0and b[e-1][g],g<L(f)-1and f[g+1],e<L(b)-1and b[e+1][g],g and f[g-1]];j=G;i=j[0]+str([[s,u][k(r,1,z)>0],4,4,k(t,0,z),0,max(1,k(r,0,z))-1][ord(j[0])%7]);b[e][g]=i;d=d|(i!=j)
 return d
while v():0
for f in b:print''.join(M(lambda j:[' ',`int(j[1:]!=u)`][j[0]!=' '],f))+'\n'

实际观看

  • 假设输入中的每一行以换行符结尾
  • 通过输出 print()
  • 每行输出以很多空白和换行符结尾

  • @ mbomb007(#34718)节省了很多字节
  • 由于@ZacharyT(#55550),节省了1个字节

您不需要通过文件进行输入和输出。您可以将stdin和stdout与input()和一起使用print。另外,str(int(bool(j[1:]!=u)))与相同`int(j[1:]!=u)`
mbomb007'8

@ mbomb007嗯,还不完全是,我仍然需要str(,但要注意的是bool(
Quelklef '16

`x`(使用反引号,是的别名repr)与str(x)(至少对于小整数是相同的。对于某些对象,long,生成器等,它是不同的)。另一场高尔夫:if g!=0与相同if g。您也可以k=lambda h,l,z:max(...
mbomb007 '16

@ mbomb007反引号不适用于Py3,并且我在此PC上没有2。如果我安装它或切换计算机,我会添加它,谢谢。
Quelklef

1
您需要这里的空间吗?print ''?可以print''吗?
扎卡里
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.