Simulatore di pietra rossa semplice


27

Redstone è un materiale nel gioco Minecraft ed è usato per molti aggeggi complessi. Per questo programma, dovrai solo simulare tre elementi: il filo di pietra rossa (indicato con R), la torcia di pietra rossa (indicato con T) e il blocco (indicato con B).

Ecco un elenco di regole di base sul funzionamento di 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

L'input verrà fornito in array bidimensionali fino a una dimensione di 64x64, in questo modo:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

È garantito che l'ingresso non avrà "orologi" o pietra rossa alimentata da una torcia che punta al blocco su cui è accesa la torcia. Ci sarà un solo circuito di pietra rossa in ogni ingresso.

Il tuo programma deve cambiare ogni carattere in 1 o 0, 1 indicando se questo oggetto è alimentato / emette potenza e uno 0 se è non alimentato / non emette potenza.

Questo input dovrebbe avere questo output:

1111
   1
100000
1
111111111
        1
   001111

Questo è un code-golf, quindi vince il codice più corto, come sempre.


1
Quale risultato ti aspetti per situazioni come "TRR\nB B\nRRT"?
Howard,

111\n0 1\n000è l'output; sembra essere solido entro le regole. Metterò una limitazione di input dicendo che non puoi avere situazioni come TRR B R RRR, in cui lampeggia ripetutamente.
beary605,

1
Possiamo supporre che ogni array di input conterrà solo un circuito completo che va dall'alto verso il basso come nell'esempio o dobbiamo codificare per più circuiti separati che iniziano in qualsiasi punto dell'array?
Graham,

@Graham: ci sarà un solo circuito di pietra rossa per ogni ingresso.
beary605,

1
Conoscendo il gioco Minecraft, penso che nel tuo esempio dato il blocco sulla linea 2 non impedisca alla torcia adiacente di dare energia (la pietra rossa non si collega effettivamente al blocco). È un errore o una semplificazione mediata?
tomsmeding

Risposte:


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 ' ')])sostituisce ogni riquadro con un elenco di se stesso seguito dai suoi quattro vicini, quindi mappa quello attraverso h. h dice per ogni tessera come reagisce ai vicini: le torce si spengono ('T' anziché 't') quando c'è un blocco di potenza ('b') nelle vicinanze, i fili ('d' per i morti attraverso 's') copiano imperfettamente il loro vicino più potente (anche se non può andare peggio che morto), ecc.

iterateripete questo passaggio, (!!(64^2+16))traccia un'iterazione in cui i circuiti aciclici vengono fatti convergere, e lo scrissi totalmente in quel modo per dare un limite intuitivo, non atterrare a 400.


4

Python, 699

Questo è solo un passaggio rapido (a corto di tempo per ora). Probabilmente può usare molto più 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))

Sì, ad esempio, è possibile utilizzare f=sete creare un l=lambda x:zip(x,[0]*len(x)). Bene, avresti ancora più di 700 caratteri. Inoltre, hai lasciato uno spazio inutile a ... or not (a,z)in o.
Morwenn,

Hai bisogno di spazio dopo la tua dichiarazione di stampa?
Zacharý,

@ZacharyT Hai ragione. Grazie!
ESultanik,

Questo è già stato detto, ma f=setnot (a,z)in o
raderebbe

Utilizzare le schede E gli spazi per alcuni risparmi di rientro.
mbomb007,

4

Python 2, 556 byte

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'

Guardalo in azione

  • Presuppone che ogni riga in input termina con una nuova riga
  • Uscite via print()
  • Ogni riga di output termina con un sacco di spazi bianchi e una nuova riga

  • Salvataggio di molti byte grazie a @ mbomb007 (# 34718)
  • Salvato 1 byte grazie a @ZacharyT (# 55550)

Non è necessario disporre di input e output tramite file. Puoi usare stdin e stdout, con input()e print. Inoltre, str(int(bool(j[1:]!=u)))è lo stesso di `int(j[1:]!=u)`.
mbomb007,

@ mbomb007 Beh, non proprio, ho ancora bisogno str(, ma un buon punto bool(.
Quelklef,

`x`(usando i backtick, è un alias per repr) è lo stesso di str(x)(per i piccoli numeri interi, almeno. È diverso per alcuni oggetti, long, generatori, ecc.). Un altro golf: if g!=0è lo stesso di if g. Puoi anche averek=lambda h,l,z:max(...
mbomb007 il

@ mbomb007 I backtick non sono per Py3 e non ne ho 2 su questo pc. Se lo installo o cambio computer, lo aggiungerò, grazie.
Quelklef,

1
Hai bisogno di spazio qui? print ''? Potrebbe essere print''?
Zacharý,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.