テーブルが与えられたら、椅子に置きます


41

チャレンジ

ASCII |とで描かれたテーブルが入力として与えられます_。あなたの仕事は、その周りに椅子を置くことです。

入力:

 ____
|    |
|    |
|    |
|    |
|____|

出力:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

これらの椅子はとで作られ<>ていv^ます。

もう一つの例:

ラインには、できるだけ多くの椅子が必要です。

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

すべての椅子の間にスペースが必要です。そして>_^_^_<無効|_^_^_|です。

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

「ドーナツ」の内側に椅子を置くことはできません。

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^およびv優先順位付け<>ます。椅子自体はありません(少なくとも1つ|または_列に並んでいる必要があります)。

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

これはコードゴルフなので、最短のコードが勝ちます。


2
私は混乱しています、なぜ椅子が横からテーブルに埋め込まれているのですか?
オプティマイザー

正しく思い出すと、元のサンドボックスポストには、垂直のテーブルラインと椅子のラインの間にスペースがありました。テーブルの水平線と椅子の間に小さなスペースがあるように。
オプティマイザー

1
椅子は互いに1の距離を置いて配置されているように見えますが、入力の周囲は2で割り切れません。プログラムが椅子を置き始める方法。時計回りまたは反時計回り?右上、左上などから?

1
また、私は、第三のサンプルに問題があると思います-第二と第三の「トップ」椅子の間に余分なスペースがあります-そしてまた、最後の例では、右下隅

1
最初のテストケースは壊れているようです。入力は、わずか4広く、出力が5である
小麦ウィザード

回答:


34

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

インデントの最初のレベルにスペース、2つのタブ、1つのタブ、3つのスペースを使用できませんか?これにより、数バイト節約できます。
ライリー

3
これが最もゴルフを解いた答えかもしれません。
魔法のタコUr

2
i,o="I "の代わりにi="I";o=" "動作しますか?
アドナン

1
@ErikGolferエリックゴルファーを作るnと、4バイトのコストがかかり、6を節約できます。
小麦ウィザード

1
@ Pietu1998それを指摘してくれてありがとう。問題を修正しました
ウィートウィザード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.