ボックスを実装する


17

ASCIIボックスは次のようになります。

++    +---+    +------+    +---+    +---+
++    |   |    |      |    |   |    |   |
      |   |    |      |    |   |    |   |
+-+   |   |    |      |    |   |    |   |
+-+   |   |    |      |    |   |    +---+
      +---+    |      |    |   |
+--+           |      |    |   |    ++
|  |           |      |    |   |    ||
|  |           +------+    |   |    ||
+--+                       |   |    ||
                           +---+    ||
                                    ||
                  +-----+           ||
+------------+    |     |           ++
|            |    |     |
|            |    |     |
+------------+    +-----+

破裂した同じASCIIボックスの例を次に示します。

++    +- -+    +-    -+    +- -+    +- -+
++    | - |    | -  - |    | - |    | - |
       | |      | -- |      | |      | |
+-+    | |       |  |        "      | - |
+-+   | - |       ||        | |     +- -+
      +- -+      |  |      |   |
+--+            | -- |      | |     ++
|  |           | -  - |      "      ||
|  |           +-    -+     | |     ||
+--+                       | - |   |  |
                           +- -+   |  |
      --                            ||
     -  -         +-   -+           ||
+-  -    -  -+    | - - |           ++
| --      -- |     | = |
| --      -- |    | - - |
+-  -    -  -+    +-   -+
     -  -
      --

コピーしやすい形式のこれらすべてのテストケースボックスへのリンクを次に示します。順序は、すべての入力に続いて同じ順序のすべての出力です。

あなたの目標は、ASCIIボックスを入力として受け取り、内包されたボックスを返すことです。内破の規則は次のとおりです。

  1. 「+」は変更されません。「-」も「|」もしません 「+」に直接隣接
  2. コーナーから始まり、「-」と「|」同じキャラクターがコーナーに近づいたよりも1スペース分内側に移動します。「-」および「|」同じ場所に移動することも、移動することもありません。
  3. 「-」と「-」が同じスポットに移動した場合、そのスポットに「=」を入れます。「|」および「|」同じ場所に移動し、その場所に「」を入れます。これらは、同じ場所で反対方向に移動するそれぞれのキャラクターの2つとしてカウントされます。
  4. 2つの「-」または2つの「|」左下の例に見られるように、互いを越えて移動できます。
  5. ボックスが十分に細い場合、同じ方法で外側に拡大し始め、常に一部から始まった側から離れます。
  6. 結果は、x方向とy方向の両方で中心線を挟んで対称になります(改行は無視されます)。これにはスペースが含まれます。そのため、結果にはスペースを満たすためにスペースを埋め込む必要があります。

ルールの詳細:

  1. これはコードゴルフなので、バイト単位の最短プログラムが優先されます。
  2. 標準の抜け穴が適用されます。
  3. 各行が改行文字で終わると仮定できます。
  4. 入力文字列の文字は「+」、「-」、「|」、「」、および「\ n」(改行)のみであり、出力文字列は「=」を追加して同じルールに従う必要がありますおよび "可能な文字として。
  5. オプションで、最後の行の末尾に単一の末尾の改行を含めることができます。
  6. 処理する必要がある最小のASCIIボックスは、左上の例です。すべてのASCIIボックスの隅には、正確に4つの「+」があります。
  7. m x n次のm,nような整数のサイズのボックスを処理する必要があります2<=m,n<256(可能な最大の文字列サイズ255*(255+1)
  8. 入力として常に単一の有効なASCIIボックスを取得すると想定できます。

ルールの詳細の数字4の出力に「可能性のある文字」を追加するのを忘れたと思います。編集:入力に空行がないと仮定できますか?
-Theraot

その1x6の例はファンキーですが、なぜそれが外側に破裂するのですか?私はそれらのいずれかを考える||ようにその例を必要としている"か何か...
マジックタコ壺

@carusocomputing左下の例と同じ、壁は互いに移動します(したがって、ボックスの容積は負になります)-ルール4および5
Lyth

@Lythはまだありません"か?"3ワイド以上にのみ表示されると思いますか?
魔法のタコ

@carusocomputingこれを考えてみてください:どこに"行きますか?左側ですか、それとも右側ですか?両方にすることはできませんが、結果が対称的であるため、どちらにすることもできません。
ハイパーニュートリノ

回答:


15

パイソン2591 555 545 527 525 496の 436 351 334 333 303バイト

s=input()
w=len(s[0])
h=len(s)
V=max(0,w/2-h)
H=max(0,h/2-w)
p=[[' ']*w]*V
q=[' ']*H
s=[q+k+q for k in p+s+p]
d,c=' -=',' |"'
exec"c,d,V,H,w,h=d,c,H,V,h,w;s=map(list,zip(*s))[::-1]\nfor j in range(h-4):q=s[V+j+2];q[H]=c[q[H]==c[2]];r=H+min(j+1,h-4-j);q[r]=c[1+(q[r]>' ')]\n"*4
for x in s:print''.join(x)

オンラインでお試しください!

編集:私の古い方法は、最初に上部と下部、次に左右を内破しました。代わりに、上部を内破し、90度回転し、それを4回行うことができます。また、私はユーザーフレンドリーなコードを使用していましたが、これはinput [['+', '-', '-', '-', '-', '-', '+'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['+', '-', '-', '-', '-', '-', '+']]いですがプログラムにとって短い形式の入力が必要です:P(それをキャッチしてくれたPhoenixに感謝します)

人間が読み取れる入力をコンピューターが読み取れる入力に変換するために使用されるTIOリンクのヘッダーコードは、Leaky Nunの功績によるものです。

Leaky Nunのおかげで-85バイト!
行全体を変数に格納して変更できるように、トップ爆縮から左爆縮に切り替えることにより、-17バイト。提案してくれたLeaky Nunに感謝します!
スペースを削除するために物事を切り替えることで-1バイト。
Leaky Nunのおかげで-30バイト!


割り当てs[0]S[0]変数には、いくつかのバイトを保存する
coinheringaahing caird

@Ilikemydogああ、そうだね。ありがとう!
-HyperNeutrino

あなたは置き換えることができますp=s[0]し、P=S[0]p=z(s[0])P=z(S[0])、それぞれ、その後のすべての出現置き換えるz(p)p、すべてz(P)ではP18のバイトを保存します。
R.カップ

また、置き換えることができ(z(s)-1)/2-pz(s)/2-.5-p(p-1)/2-z(s)してp/2-.5-z(s)2つの以上のバイトを保存します。
R.カップ

@ R.Kapああ大丈夫。両方の提案をありがとう!
ハイパーニュートリノ

1

C(clang)、693バイト

読みやすくするために新しい行が追加されました。最初の2つは必須ですが、残りは必須ではありません。

#define P B[i][l]
#define m malloc(8)
I(B,h,V,S,J,Z,i,j,l,n,H,W,c,C,a,z,_,L,G,u,N,M)char**B,**Z;char*L,*G,*u;{
V=strlen(B[0]);
S=J=0;
Z=m;
for(i=0,j=h-1;i<h/2+h%2;i++,j--){
for(l=0,n=V-1;l<V/2+V%2;l++,n--){
if(P!=43&&((B[i][l-1]!=43&&i<1)||(B[i-1][l]!=43&&l<1))){
H=P==45;
W=P=='|';
P=B[j][l]=B[i][n]=B[j][n]=32;
if(H){
c=(N=i+l-1)==(M=j-l+1)?61:45;
if(M<0)L=m,sprintf(L,"%*s",V,""),L[l]=L[n]=c,Z[J]=L,J++;
else B[N][l]=B[N][n]=B[M][l]=B[M][n]=c;
}
if(W){
c=(N=l+i-1)==(M=n-i+1)?34:'|';
if(M<0)G=m,sprintf(G,"|%*s%s%*s|",i-n-2,"",B[i],i-n-2,""),B[i]=B[j]=G,S++;
else B[i][N]=B[j][N]=B[i][M]=B[j][M]=c;
}
}
}
}
for(a=-J+1;a<=h+J;u=a<1?Z[-a]:a<=h?B[a-1]:Z[a-h-1],C=S+1-strlen(u)/2,printf("%*s%s\n",C>0?C:0,"",u),a++);
}

大きな挑戦をありがとう!それはかなりトリッキーでしたが、私はまだたくさんの楽しみがありました。

これは、入力をコマンドライン引数として受け取り、内包されたボックスの複数行文字列をSTDOUTに出力します。いつものように、ゴルフのヒントは大歓迎です。

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.