シンプルなレッドストーンシミュレーター


27

RedstoneはゲームMinecraftの素材であり、多くの複雑な仕掛けに使用されます。このプログラムでは、レッドストーンワイヤ(Rで表記)、レッドストーントーチ(Tで表記)、およびブロック(Bで表記)の3つのアイテムのみをシミュレートする必要があります。

以下に、レッドストーンの仕組みに関する基本的なルールのリストを示します。

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

入力は、次のように最大64x64のサイズの2次元配列で提供されます。

TRRR
   B
TBRTRR
R
RRRRRRRRR
        R
   RRRRRR

入力に「クロック」、またはトーチがオンになっているブロックを指すトーチを動力とするレッドストーンがないことが保証されています。すべての入力に1つだけのレッドストーン回路があります。

プログラムは、各文字を1または0に変更する必要があります。1は、このアイテムに電力が供給されている/電力を放出していることを示し、0は電力が供給されていない/電力を放出していない場合に0です。

この入力には次の出力が必要です。

1111
   1
100000
1
111111111
        1
   001111

これはコードゴルフですので、いつものように最短のコードが勝ちます。


1
次のような状況ではどのような出力が期待され"TRR\nB B\nRRT"ますか?
ハワード

111\n0 1\n000出力です。ルールの範囲内で健全なようです。TRR B R RRR繰り返し点滅するようなのような状況はあり得ないと言う入力制限を付けます。
beary605

1
あなたの例のように、各入力配列には上から下に実行される完全な回路が1つだけ含まれると仮定できますか、または配列のどこからでも開始する複数の個別の回路をコーディングする必要がありますか?
グラハム

@Graham:各入力に1つのレッドストーン回路のみがあります。
beary605

1
ゲームMinecraftを知っているので、2行目のブロックで与えられた例では、隣接するトーチが電力を供給するのを止めませ(レッドストーンは実際にはブロックに接続しません)。これはエラーですか、それとも単純化ですか?
tomsmeding

回答:


4

ハスケル、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 ' ')])は、各タイルをそれ自体のリストとそれに続く4つの隣人に置き換え、それをhにマップします。hは、各タイルに対して隣人にどのように反応するかを示します:近くに電源ブロック(「b」)があるとトーチがオフ(「t」ではなく「T」)になり、ワイヤー(「d」はデッドスルー「s」)が不完全にコピーします最も強力な隣人(死ぬほど悪化することはありませんが)など

iterateこのステップを(!!(64^2+16))繰り返して、非循環回路が収束する繰り返しを取り出し、私は完全にそのように書いて、400で着陸するのではなく、直感的な境界を与えます。


4

Python、699

これはただの簡単なパスです(今のところ時間切れです)。おそらくもっと多くのゴルフを使用できます。

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

はい、たとえば、を使用f=setして作成できますl=lambda x:zip(x,[0]*len(x))。まあ、あなたはまだ700文字以上になるでしょう。また、あなたは無駄なスペースを残しました... or not (a,z)in o
モーウェン

印刷文の後にスペースが必要ですか?
ザカリー

@ZacharyTそのとおりです。ありがとう!
ESultanik

これはすでに言われましたf=setが、いくつかの文字を剃るでしょう、そしてあなたは別の役に立たない文字を持っています@not (a,z)in o
ザカリー

インデントの節約のためにタブとスペースを使用します
mbomb007

4

Python 2、556バイト

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'

実際にご覧ください

  • 入力の各行が改行で終わると仮定します
  • を介した出力 print()
  • 出力の各行は、たくさんの空白と改行で終わります

  • @ mbomb007のおかげで多くのバイトを節約(#34718)
  • @ZacharyTのおかげで1バイトを節約(#55550)

ファイルを介して入力および出力する必要はありません。およびとともにinput()、stdinおよびstdoutを使用できますprint。また、str(int(bool(j[1:]!=u)))と同じ`int(j[1:]!=u)`です。
mbomb007

@ mbomb007まあ、まったくではなく、まだ必要ですがstr(、良い点がありbool(ます。
-Quelklef

`x`(バックティックを使用すると、のエイリアスになりますrepr)と同じですstr(x)(少なくとも小さな整数の場合、特定のオブジェクト、long、ジェネレーターなどでは異なります)。別のゴルフ:はとif g!=0同じif gです。あなたも持つことができますk=lambda h,l,z:max(...
mbomb007

@ mbomb007 BackticksはPy3用ではありません。このPCには2つありません。インストールしたり、コンピューターを切り替えたりした場合は、追加します、ありがとう。
Quelklef

1
ここにスペースが必要ですか?print ''?それができますprint''か?
ザカリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.