Simulador simple de redstone

27

Redstone es un material en el juego Minecraft, y se usa para muchos artilugios complejos. Para este programa, solo necesitará simular tres elementos: el cable de redstone (señalado con R), la antorcha de redstone (señalada con T) y el bloque (señalado con B).

Aquí hay una lista de reglas básicas sobre cómo funciona redstone:

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

La entrada se proporcionará en matrices bidimensionales de hasta 64x64, de esta manera:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

Se garantiza que la entrada no tendrá ningún "reloj" o redstone alimentado por una antorcha que apunte al bloque en el que está encendida. Solo habrá un circuito de redstone en cada entrada.

Su programa debe cambiar cada carácter para que sea 1 o 0, 1 que indica si este elemento tiene potencia / potencia de emisión, y un 0 si no tiene potencia / no está emitiendo potencia.

Esta entrada debe tener esta salida:

1111
   1
100000
1
111111111
        1
   001111

Este es un código de golf, por lo que el código más corto gana, como siempre.

beary605
fuente
1
¿Qué salida esperas para situaciones como "TRR\nB B\nRRT"?
Howard
111\n0 1\n000es la salida; parece estar dentro de las reglas. Pondré una restricción de entrada diciendo que no puede tener situaciones como TRR B R RRR, donde parpadea repetidamente.
beary605
1
¿Podemos suponer que cada matriz de entrada contendrá solo un circuito completo que se ejecuta de arriba a abajo como en su ejemplo o tenemos que codificar múltiples circuitos separados que comiencen en cualquier parte de la matriz?
Graham el
@Graham: Solo habrá un circuito de redstone para cada entrada.
beary605
1
Conociendo el juego Minecraft, creo que en tu ejemplo dado el bloque en la línea 2 no impide que la antorcha adyacente dé poder (la piedra roja en realidad no se conecta al bloque). ¿Es esto un error o una simplificación intencionada?
tomsmeding

Respuestas:

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 ' ')])reemplaza cada mosaico por una lista de sí mismo seguido de sus cuatro vecinos, luego los asigna a través de h. h dice para cada mosaico cómo reacciona ante los vecinos: las antorchas se apagan ('T' en lugar de 't') cuando hay un bloque de alimentación ('b') cerca, los cables ('d' por muerto a través de 's') se copian de forma imperfecta su vecino más poderoso (aunque no puede ser peor que muerto), etc.

iteraterepite este paso, (!!(64^2+16))arranca una iteración en la que los circuitos acíclicos se hacen convergentes, y lo escribí totalmente así para dar un límite intuitivo, no aterrizar en 400.

Gurkenglas
fuente
4

Python, 699

Esto es solo un pase rápido (se acabó el tiempo por ahora). Probablemente pueda usar mucho más golf.

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
fuente
Sí, por ejemplo, podría usar f=sety crear un l=lambda x:zip(x,[0]*len(x)). Bueno, todavía tendrías más de 700 caracteres. Además, dejaste un espacio inútil en ... or not (a,z)in o.
Morwenn
¿Necesita el espacio después de su extracto de impresión?
Zacharý
@ZacharyT Tienes razón. ¡Gracias!
ESultanik
Esto ya se dijo, pero f=setafeitaría algunos caracteres, y tienes otro personaje inútil @not (a,z)in o
Zacharý
Use pestañas Y espacios para algunos ahorros de sangría.
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'

Véalo en acción

  • Asume que cada línea en la entrada termina con una nueva línea
  • Salidas vía print()
  • Cada línea de salida termina con muchos espacios en blanco y una nueva línea

  • Muchos bytes guardados gracias a @ mbomb007 (# 34718)
  • Guardado 1 byte gracias a @ZacharyT (# 55550)
Quelklef
fuente
No es necesario tener entrada y salida a través de archivos. Puede usar stdin y stdout, con input()y print. Además, str(int(bool(j[1:]!=u)))es lo mismo que `int(j[1:]!=u)`.
mbomb007
@ mbomb007 Bueno, no del todo, todavía necesito el str(, pero buen punto bool(.
Quelklef
`x`(usando backticks, es un alias para repr) es lo mismo que str(x)(para enteros pequeños, al menos. Es diferente para ciertos objetos, largos, generadores, etc.). Otro golf: if g!=0es el mismo que if g. También puede tenerk=lambda h,l,z:max(...
mbomb007
@ mbomb007 Los backticks no son para Py3 , y no tengo 2 en esta PC. Si lo instalo o cambio de computadora, lo agregaré, gracias.
Quelklef
1
¿Necesitas el espacio aquí? print ''? Podría ser print''?
Zacharý