Python 2、1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443バイト
Rileyのおかげで6バイト節約
Adnanのおかげで6バイト節約
この質問は1年以上前のものであり、まだ回答がないため、試してみようと思いました。
n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
A=a[x];B=a[x+1];C=a[x-1]
for y in R(z):
D=A[y-1:y+2];k=B[y];j=A[y+1]
if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)
オンラインでお試しください!
プログラムは、テーブルの名前の付いたファイルを読み取り、テーブルをI
椅子とともに印刷しますstd::out
。多数のエッジケースについて確信が持てなかったので、最善の判断を下しました(最も労力がかからなかったものは何でも)が、すべてのテストケースに合格したようです。一部の出力は正確に一致しませんが、すべて同じ数の椅子があります。
説明
最初の行は、将来的にバイトを節約するいくつかの定義を設定するだけです。
(将来の行で読みやすくするためにこれらのマクロを解凍します)
n,i,o="\nI ";R=lambda x:range(1,x-1)
次にI
、そのための短い変数が既にあるので、数バイトを節約するという名前のファイルを開きます。
b=open("I").read().split("\n")
改行に沿って分割し、文字列のリスト(画像の行)を作成します
s=b.split(n)
次に、最も長い行の長さを見つけて、すべての行をその長さまで埋めることができます。(追加のパディングが少し必要なので、3を追加します)
z=max(map(len,s))+3
次に、実際のパディングを実行してI
、エッジの周りに文字の境界線を作成します。これは、後で形状の内側と外側の違いを伝える必要があるためです。また、データ型を文字列のリストから文字のリスト(長さ1の文字列)に変更します。
a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]
次の行は、もう1つのバイト保存定義です。
(これも開梱します)
B=R(len(a))
ここI
で、図形の外側のすべての場所に文字を広げたいと思います。擬似セルラーオートマトンを使用してこれを行うことができます。それぞれI
が隣接する
キャラクターに広がります。オートマトンが安定するまでループできますが、これは文字数よりも多くの反復を取ることができないため、b
(元の入力)のすべての文字をループするだけです
for _ in b:
反復ごとに、2Dリスト内のすべての文字を渡します(最も外側のパディングを除く)
for x in range(1,len(a)-1):
A=a[x] #<--Another definition I will fill in for clarity
for y in range(1,z-1):
各位置に対して、次のコードを実行します。
if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "
これを分解しましょう。
&
(ビットごとand
)で区切られた2つの条件を持つifがあります
最初のものI
は、隣接するセルのいずれかに存在するかどうかを単純にチェックし、2番目のものは現在のセルがであるかどうかだけをチェックします" "
。これらの条件を渡すと、現在のセルをに設定しますI
。
形状の外側と内側を決定したので、テーブルの周りに椅子を配置することができます。
もう一度、すべてのセルをループします(さらにいくつかの略記を設定します)
for x in range(1,len(a)-1):
A=a[x]
for y in range(1,z-1):
k=a[x+1][y]
これが私のお気に入りの部分です。退屈な、ほとんど定義ベースの、これまでのゴルフを駆け抜けてきたなら、巧妙なゴルフの素敵な小片であなたに報いるつもりです(私がそう言うなら)。
Pythonの背景:
Pythonでは、辞書キーを2回割り当てようとすると、後者に割り当てられます。例えば
>>> {1:"a",1:"b"}[1]
'b'
このプロパティを悪用して、現在のセルを特定のキャラクターに割り当てます。
最初の条件は
if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]
セルが3 _
文字の端の中央にある場合、現在のセルとその下のセルを再割り当てします。によってオーバーロードされた辞書のインデックス作成の結果に割り当てI
ます。最初にペアでデフォルトを設定します。"I":"_"+a[x+1][y]
つまり、変更がない場合は、2つのセルを元の値に割り当てます。次に、ペアを追加しa[x-1][y]:"^ "
ます。現在のセル(a[x-1][y]
)の上のセルがで満たされない限り、これは(重要な)何もしませんI
。その中にある場合I
、現在のセルに椅子を配置するように指示するデフォルトをオーバーライドします。次に、現在のセルの下にあるセルに移動しI
ます。そのセルを再度オーバーライドして、現在のスポットの下に上向きの椅子を配置します。
次の条件は少しシンプルです
if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]
現在のセルとその上のセルが両方かどうかを確認し|
ます。その場合、辞書を設定します。
辞書の最初のペア"I":"|"
はデフォルトを設定します。キーが再割り当てされないI
場合、キーにアクセスするため、I
デフォルト|
(元の文字)に戻り、何もしません。
2つのキーを追加します。A[y+1]:">",A[y-1]:"<"
左右の2つのセルのいずれかがあればI
、現在のセルを外側の方向を指す椅子に再割り当てします。
ここで出力する必要があります。ただし、印刷することはできません。最初に行う必要があるハウスキーピング作業がいくつかあります。再び文字列に変換し、I
作成したすべてのを削除する必要があります。これは1行で行われます。
print "\n".join(`y`[2::5]for y in a).replace("I"," ")