Prosty symulator Redstone

27

Redstone jest materiałem w grze Minecraft i jest wykorzystywany do wielu skomplikowanych urządzeń. W tym programie będziesz musiał tylko zasymulować trzy elementy: drut z czerwonego kamienia (oznaczony literą R), pochodnia z czerwonego kamienia oznaczony literą T i blok (oznaczony literą B).

Oto lista podstawowych zasad dotyczących działania 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

Dane wejściowe będą podawane w tablicach dwuwymiarowych do rozmiaru 64 x 64, takich jak to:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

Gwarantujemy, że wejście nie będzie miało żadnych „zegarów” ani czerwonego kamienia zasilanego pochodnią wskazującą blok, w którym latarka jest włączona. Na każdym wejściu będzie tylko jeden obwód redstone.

Twój program musi zmienić każdy znak na 1 lub 0, 1 wskazujący, czy ten element jest zasilany / emitujący moc, oraz 0, jeśli nie jest zasilany / nie emituje mocy.

Dane wejściowe powinny mieć następujące dane wyjściowe:

1111
   1
100000
1
111111111
        1
   001111

To jest golf golfowy, więc jak najkrótszy kod wygrywa.

beary605
źródło
1
Jakiej wydajności oczekujesz w takich sytuacjach "TRR\nB B\nRRT"?
Howard
111\n0 1\n000jest wyjściem; wydaje się, że jest to zgodne z zasadami. Wprowadzę ograniczenie wejściowe, mówiąc, że nie możesz mieć takich sytuacji TRR B R RRR, w których wielokrotnie miga.
beary605
1
Czy możemy założyć, że każda tablica wejściowa będzie zawierać tylko jeden kompletny obwód biegnący od góry do dołu, jak w twoim przykładzie, czy też musimy kodować wiele oddzielnych obwodów zaczynających się w dowolnym miejscu tablicy?
Graham
@Graham: Będzie tylko jeden obwód czerwonego kamienia dla każdego wejścia.
beary605
1
Znając grę Minecraft, myślę, że w twoim przykładzie podany blok na linii 2 nie powstrzymuje sąsiedniej pochodni od dawania mocy (czerwony kamień tak naprawdę nie łączy się z blokiem). Czy to błąd, czy zamierzone uproszczenie?
tomsmeding

Odpowiedzi:

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 ' ')])zastępuje każdy kafelek listą samych siebie, a następnie czterema sąsiadami, a następnie odwzorowuje to do h. h mówi dla każdego kafelka, jak reaguje na sąsiadów: Pochodnie wyłączają się („T” zamiast „t”), gdy w pobliżu znajduje się blok mocy („b”), przewody („d” dla martwych przez „s”) niedokładnie kopiują ich najsilniejszy sąsiad (choć nie może stać się gorzej niż martwy) itp.

iteratepowtarza ten krok, (!!(64^2+16))opracowuje iterację, w której obwody acykliczne są zbieżne, i całkowicie napisałem to w ten sposób, aby dać intuicyjną granicę, a nie wylądować na 400.

Gurkenglas
źródło
4

Python, 699

To tylko szybkie przejście (na razie zabrakło czasu). Prawdopodobnie przydałoby się o wiele więcej gry w golfa.

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
źródło
Tak, na przykład, możesz użyć f=seti stworzyć l=lambda x:zip(x,[0]*len(x)). Nadal będziesz mieć ponad 700 znaków. Ponadto pozostawiłeś bezużyteczne miejsce na ... or not (a,z)in o.
Morwenn
Czy potrzebujesz miejsca po wyciągu?
Zacharý 16.04.17
@ZacharyT Masz rację. Dzięki!
ESultanik
To już zostało powiedziane, ale f=setnot (a,z)in o
ogoliłoby
Aby zaoszczędzić wcięcia, użyj tabulatorów i spacji .
mbomb007 17.04.17
4

Python 2, 556 bajtów

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'

Zobacz to w akcji

  • Zakłada, że ​​każda linia na wejściu kończy się nową linią
  • Wyjście przez print()
  • Każda linia wyjściowa kończy się dużą ilością białych znaków i nowej linii

  • Zaoszczędzono wiele bajtów dzięki @ mbomb007 (# 34718)
  • Zapisano 1 bajt dzięki @ZacharyT (# 55550)
Quelklef
źródło
Nie musisz mieć danych wejściowych i wyjściowych za pośrednictwem plików. Możesz użyć stdin i stdout, używając input()i print. Ponadto str(int(bool(j[1:]!=u)))jest taki sam jak `int(j[1:]!=u)`.
mbomb007
@ mbomb007 Cóż, nie całkiem, wciąż potrzebuję str(, ale dobry punkt bool(.
Quelklef
`x`(przy użyciu odwrotnych znaków jest to alias dla repr) jest taki sam jak str(x)(przynajmniej dla małych liczb całkowitych. Jest różny dla niektórych obiektów, długich, generatorów itp.). Kolejny golf: if g!=0jest taki sam jak if g. Możesz również miećk=lambda h,l,z:max(...
mbomb007
@ mbomb007 Backticks niedla Py3 i nie mam 2 na tym komputerze. Jeśli go zainstaluję lub zmienię komputery, dodam to, dzięki.
Quelklef
1
Potrzebujesz tutaj miejsca? print ''? Czy to możliwe print''?
Zacharý 16.04.17