Simulador simples de redstone

27

Redstone é um material no jogo Minecraft, e é usado para muitas engenhocas complexas. Para este programa, você precisará simular apenas três itens: o fio redstone (anotado com R), a tocha redstone (anotada com T) e o bloco (anotado com B).

Aqui está uma lista de regras básicas sobre como o redstone funciona:

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

A entrada será fornecida em matrizes bidimensionais até um tamanho de 64x64, assim:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

É garantido que a entrada não terá nenhum "relógio" ou redstone alimentado por uma tocha apontando para o bloco em que a tocha está ligada. Haverá apenas um circuito redstone em cada entrada.

Seu programa deve alterar cada caractere para 1 ou 0, 1 indicando se este item está energizado / emitindo energia e 0 se ele não estiver energizado / não emitindo energia.

Esta entrada deve ter esta saída:

1111
   1
100000
1
111111111
        1
   001111

Este é um código de golfe, o código mais curto vence, como sempre.

beary605
fonte
1
Que resultado você espera para situações como essa "TRR\nB B\nRRT"?
275 Howard Howard
111\n0 1\n000é a saída; parece ser bom dentro das regras. Vou colocar uma restrição de entrada dizendo que você não pode ter nenhuma situação como TRR B R RRR, onde pisca repetidamente.
beary605
1
Podemos assumir que cada matriz de entrada conterá apenas um circuito completo, de cima para baixo, como no seu exemplo, ou será necessário codificar vários circuitos separados, iniciando em qualquer lugar da matriz?
Graham
@ Graham: Haverá apenas um circuito redstone para cada entrada.
precisa saber é o seguinte
1
Conhecendo o jogo Minecraft, acho que no seu exemplo, dado o bloco na linha 2, não impede a tocha adjacente de fornecer energia (a redstone na verdade não se conecta ao bloco). Isso é um erro ou uma simplificação?
tomsmeding

Respostas:

4

Haskell, 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 ' ')])substitui cada bloco por uma lista de si mesma seguida por seus quatro vizinhos e depois mapeia isso por h. h diz para cada bloco como reage aos vizinhos: tochas se apagam ('T' em vez de 't') quando há um bloco de energia ('b') por perto, fios ('d' para mortos por 's') copiam imperfeitamente seu vizinho mais poderoso (embora não possa piorar do que morrer), etc.

iteraterepete esta etapa, (!!(64^2+16))realiza uma iteração na qual os circuitos acíclicos terminam convergindo, e eu a escrevi totalmente assim para fornecer um limite intuitivo, para não aterrissar em 400.

Gurkenglas
fonte
4

Python, 699

Este é apenas um passe rápido (sem tempo por enquanto). Provavelmente pode usar muito mais golfe.

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))
ESultanik
fonte
Sim, por exemplo, você pode usar f=sete criar um l=lambda x:zip(x,[0]*len(x)). Bem, você ainda teria mais de 700 caracteres. Além disso, você deixou um espaço inútil em ... or not (a,z)in o.
Morwenn 5/07
Você precisa do espaço após a sua declaração impressa?
precisa saber é o seguinte
@ZacharyT Você está certo. Obrigado!
ESultanik
Isso já foi dito, mas f=setiria raspar alguns caracteres, e você tem um outro personagem inútil @not (a,z)in o
Zachary
Use tabulações E espaços para algumas economias de indentação.
mbomb007
4

Python 2, 556 bytes

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'

Veja em ação

  • Assume que cada linha na entrada termina com uma nova linha
  • Saídas via print()
  • Cada linha de saída termina com muito espaço em branco e uma nova linha

  • Economizou muitos bytes graças a @ mbomb007 (# 34718)
  • Guardado 1 byte graças a @ZacharyT (# 55550)
Quelklef
fonte
Você não precisa ter entrada e saída através de arquivos. Você pode usar stdin e stdout, com input()e print. Além disso, str(int(bool(j[1:]!=u)))é o mesmo que `int(j[1:]!=u)`.
Mbomb007
@ mbomb007 Bem, não exatamente, eu ainda preciso do str(, mas bom argumento bool(.
Quelklef
`x`(usando backticks, é um apelido para repr) é o mesmo que str(x)(para números inteiros pequenos, pelo menos. É diferente para certos objetos, longs, geradores etc.). Outro golfe: if g!=0é o mesmo que if g. Você também pode terk=lambda h,l,z:max(...
mbomb007
@ mbomb007 Backticks não são para Py3 , e eu não tenho 2 neste pc. Se eu instalar ou trocar de computador, adicionarei isso, obrigado.
Quelklef
1
Você precisa do espaço aqui? print ''? Poderia ser print''?
Zacharý 16/04