Simulator redstone sederhana

27

Redstone adalah bahan dalam gim Minecraft, dan digunakan untuk banyak alat rumit. Untuk program ini, Anda hanya perlu mensimulasikan tiga item: kawat redstone (dicatat dengan R), obor redstone (dicatat dengan T), dan blok (dicatat dengan B).

Berikut adalah daftar aturan dasar tentang cara kerja 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

Input akan diberikan dalam array dua dimensi hingga ukuran 64x64, seperti ini:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

Dijamin bahwa input tidak akan memiliki "jam", atau redstone didukung oleh obor yang menunjuk ke blok bahwa obor aktif. Hanya akan ada satu sirkuit redstone di setiap input.

Program Anda harus mengubah setiap karakter menjadi 1 atau 0, 1 yang menunjukkan apakah item ini bertenaga / memancarkan daya, dan 0 jika tidak bertenaga / tidak memancarkan daya.

Input ini harus memiliki output ini:

1111
   1
100000
1
111111111
        1
   001111

Ini adalah kode-golf, sehingga kode terpendek menang, seperti biasa.

beary605
sumber
1
Output apa yang Anda harapkan untuk situasi seperti "TRR\nB B\nRRT"?
Howard
111\n0 1\n000adalah output; tampaknya masuk akal dalam aturan. Saya akan meletakkan batasan input yang mengatakan Anda tidak dapat memiliki situasi seperti TRR B R RRR, di mana berkedip berulang kali.
beary605
1
Bisakah kita berasumsi bahwa setiap array input hanya akan berisi satu sirkuit lengkap yang berjalan dari atas ke bawah seperti dalam contoh Anda atau apakah kita harus kode untuk beberapa sirkuit terpisah mulai dari mana saja di dalam array?
Graham
@ Graham: Hanya akan ada satu sirkuit redstone untuk setiap input.
beary605
1
Mengetahui permainan Minecraft, saya pikir dalam contoh Anda memberi blok pada baris 2 tidak menghentikan obor yang berdekatan dari memberikan kekuatan (redstone sebenarnya tidak terhubung ke blok). Apakah ini kesalahan atau penyederhanaan yang dimaksud?
mulai

Jawaban:

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 ' ')])mengganti setiap ubin dengan daftar itu sendiri diikuti oleh empat tetangganya, lalu memetakannya melalui h. h mengatakan untuk setiap ubin bagaimana itu bereaksi terhadap tetangga: Obor mati ('T' daripada 't') ketika ada blok daya ('b') di dekatnya, kabel ('d' untuk mati melalui 's') menyalin secara tidak sempurna tetangga paling bertenaga mereka (meskipun tidak bisa lebih buruk daripada mati), dll.

iteratemengulangi langkah ini, (!!(64^2+16))memetik iterasi di mana sirkuit asiklik dilakukan konvergen, dan saya benar-benar menulisnya seperti itu untuk memberikan batas intuitif, bukan untuk mendarat di 400.

Gurkenglas
sumber
4

Python, 699

Ini hanya lulus cepat (kehabisan waktu sekarang). Mungkin bisa menggunakan golf lebih banyak.

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
sumber
Yap, misalnya, Anda bisa menggunakan f=setdan membuat l=lambda x:zip(x,[0]*len(x)). Nah, Anda masih lebih dari 700 karakter. Juga, Anda meninggalkan ruang yang tidak berguna di ... or not (a,z)in o.
Morwenn
Apakah Anda membutuhkan ruang setelah pernyataan cetak Anda?
Zacharý
@ Zakary Anda benar. Terima kasih!
ESultanik
Ini sudah dikatakan, tetapi f=setakan mencukur beberapa karakter, dan Anda memiliki karakter lain yang tidak berguna @not (a,z)in o
Zacharý
Gunakan tab DAN spasi untuk penghematan lekukan.
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'

Lihat itu dalam aksi

  • Asumsikan setiap baris dalam input diakhiri dengan baris baru
  • Keluaran melalui print()
  • Setiap baris output berakhir dengan banyak spasi dan baris baru

  • Menyimpan banyak byte berkat @ mbomb007 (# 34718)
  • Disimpan 1 byte berkat @ZacharyT (# 55550)
Quelklef
sumber
Anda tidak diharuskan memiliki input dan output melalui file. Anda dapat menggunakan stdin dan stdout, dengan input()dan print. Juga, str(int(bool(j[1:]!=u)))sama dengan `int(j[1:]!=u)`.
mbomb007
@ mbomb007 Yah, tidak cukup, saya masih membutuhkan str(, tapi bagus tentang bool(.
Quelklef
`x`(menggunakan backticks, ini alias untuk repr) sama dengan str(x)(untuk bilangan bulat kecil, setidaknya. Ini berbeda untuk objek tertentu, rindu, generator, dll). Golf lain: if g!=0sama dengan if g. Anda juga dapat memilikik=lambda h,l,z:max(...
mbomb007
@ mbomb007 Backticks bukan untuk Py3 , dan saya tidak punya 2 di pc ini. Jika saya menginstalnya atau mengganti komputer, saya akan menambahkannya, terima kasih.
Quelklef
1
Apakah Anda memerlukan ruang di sini? print ''? Mungkinkah itu print''?
Zacharý