Einfacher Redstone-Simulator


27

Redstone ist ein Material im Spiel Minecraft und wird für viele komplexe Erfindungen verwendet. Für dieses Programm müssen Sie nur drei Elemente simulieren: den Redstone-Draht (mit R gekennzeichnet), den Redstone-Brenner (mit T gekennzeichnet) und den Block (mit B gekennzeichnet).

Hier ist eine Liste der Grundregeln für die Funktionsweise von 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

Die Eingabe erfolgt in zweidimensionalen Arrays bis zu einer Größe von 64 x 64 wie folgt:

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

Es ist garantiert, dass der Eingang keine "Uhren" oder roten Steine ​​hat, die von einer Taschenlampe angetrieben werden, die auf den Block zeigt, auf dem die Taschenlampe läuft. In jedem Eingang befindet sich nur ein Redstone-Kreis.

Ihr Programm muss jedes Zeichen auf eine 1 oder eine 0 ändern, wobei 1 angibt, ob dieser Gegenstand mit Strom versorgt wird / Leistung abgibt, und eine 0, wenn er nicht mit Strom versorgt wird / Leistung abgibt.

Dieser Eingang sollte diesen Ausgang haben:

1111
   1
100000
1
111111111
        1
   001111

Dies ist ein Code-Golf, also gewinnt der kürzeste Code wie immer.


1
Welche Leistung erwarten Sie für Situationen wie "TRR\nB B\nRRT"?
Howard

111\n0 1\n000ist die Ausgabe; es scheint in den Regeln solide zu sein. Ich werde eine Eingabebeschränkung setzen, die besagt, dass Sie keine Situationen haben können TRR B R RRR, in denen es wiederholt blinkt.
beary605

1
Können wir davon ausgehen, dass jedes Eingangsarray nur einen vollständigen Schaltkreis enthält, der von oben nach unten verläuft, wie in Ihrem Beispiel, oder müssen wir mehrere separate Schaltkreise codieren, die an einer beliebigen Stelle im Array beginnen?
Graham

@ Abraham: Es wird nur einen Redstone-Schaltkreis für jeden Eingang geben.
beary605

1
Ich kenne das Spiel Minecraft und denke, dass der Block in Zeile 2 in Ihrem Beispiel die benachbarte Fackel nicht daran hindert , Energie zu spenden (der Redstone verbindet sich nicht wirklich mit dem Block). Ist das ein Fehler oder eine beabsichtigte Vereinfachung?
Tomsmeding

Antworten:


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 ' ')])Ersetzt jede Kachel durch eine Liste von sich selbst, gefolgt von ihren vier Nachbarn, und ordnet diese dann durch h zu. h sagt für jedes Plättchen, wie es auf Nachbarn reagiert: Fackeln schalten sich aus ('T' statt 't'), wenn sich ein Stromblock ('b') in der Nähe befindet, Drähte ('d' für tot durch 's') kopieren fehlerhaft ihr leistungsstärkster Nachbar (obwohl er nicht schlimmer als tot sein kann) usw.

iterateWiederholt diesen Schritt, (!!(64^2+16))löscht eine Iteration, bei der azyklische Schaltungen konvergiert werden, und ich habe es total so geschrieben, um eine intuitive Grenze zu geben, nicht um bei 400 zu landen.


4

Python, 699

Dies ist nur ein kurzer Pass (momentan ist die Zeit abgelaufen). Es kann wahrscheinlich viel mehr Golfspielen gebrauchen.

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))

Ja, Sie könnten zum Beispiel eine verwenden f=setund erstellen l=lambda x:zip(x,[0]*len(x)). Du wärst immer noch über 700 Zeichen. Außerdem haben Sie einen nutzlosen Platz bei hinterlassen ... or not (a,z)in o.
Morwenn

Benötigen Sie das Leerzeichen nach Ihrem Ausdruck?
Zacharý

@ ZacharyT Du hast recht. Vielen Dank!
ESultanik

Dies wurde bereits gesagt, aber f=setwürde ein paar Zeichen rasieren, und Sie haben einen anderen nutzlosen Charakter @not (a,z)in o
Zacharý

Verwenden Sie Tabulatoren UND Leerzeichen, um Einrückungen zu vermeiden.
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'

Sehen Sie es in Aktion

  • Angenommen, jede Zeile in der Eingabe endet mit einer neuen Zeile
  • Ausgänge über print()
  • Jede Ausgabezeile endet mit vielen Leerzeichen und einer neuen Zeile

  • Viele Bytes gespart dank @ mbomb007 (# 34718)
  • 1 Byte dank @ZacharyT gespeichert (# 55550)

Sie müssen keine Ein- und Ausgabe über Dateien vornehmen. Sie können stdin und stdout mit input()und verwenden print. Auch str(int(bool(j[1:]!=u)))ist das gleiche wie `int(j[1:]!=u)`.
mbomb007

@ mbomb007 Naja, nicht ganz, ich brauche noch den str(, aber guten Punkt dazu bool(.
Quelklef

`x`(mit Backticks, es ist ein Alias ​​für repr) ist dasselbe wie str(x)(zumindest für kleine ganze Zahlen. Es ist für bestimmte Objekte, Longs, Generatoren usw. unterschiedlich). Ein weiterer Golf: if g!=0ist das gleiche wie if g. Sie können auch habenk=lambda h,l,z:max(...
mbomb007

@ mbomb007 Backticks sind nicht für Py3 und ich habe keine 2 auf diesem PC. Wenn ich es installiere oder Computer wechsle, füge ich das hinzu, danke.
Quelklef

1
Benötigen Sie den Platz hier? print ''? Könnte es sein print''?
Zacharý
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.