Implode the Box

17

Kotak ASCII terlihat seperti ini:

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

Berikut adalah beberapa contoh kotak ASCII yang sama, meledak:

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

Sini ini tautan ke semua kotak uji ini dalam format yang lebih mudah disalin. Urutannya adalah semua input diikuti oleh semua output dalam urutan yang sama.

Tujuan Anda adalah untuk mengambil kotak ASCII sebagai input, dan mengembalikan kotak yang meledak. Aturan ledakan adalah:

  1. "+" tidak pernah berubah; tidak melakukan "-" atau "|" berbatasan langsung dengan "+"
  2. Mulai dari sudut, "-" dan "|" bergerak ke dalam oleh satu spasi lebih dari karakter yang sama lebih dekat ke sudut itu. Jika "-" dan "|" akan pernah pindah ke tempat yang sama, tidak bergerak.
  3. Jika "-" dan "-" pindah ke tempat yang sama, letakkan "=" di tempat itu. Jika "|" dan "|" pindah ke tempat yang sama, letakkan "di tempat itu. Ini dihitung sebagai dua karakter masing-masing di tempat yang sama bergerak dalam arah yang berlawanan.
  4. Dua "-" atau dua "|" dapat bergerak melewati satu sama lain, seperti yang terlihat di contoh kiri bawah.
  5. Jika kotaknya cukup kurus, itu akan mulai mengembang ke arah luar dengan cara yang sama, selalu menjauh dari sisi yang dimulai dari bagian itu.
  6. Hasilnya harus simetris di garis tengah di kedua arah x dan y (mengabaikan baris baru); ini termasuk spasi, jadi hasilnya mungkin perlu diisi dengan spasi untuk memenuhi itu.

Detail Aturan:

  1. Ini adalah kode-golf, jadi program terpendek dalam byte menang.
  2. Celah standar berlaku.
  3. Anda dapat mengasumsikan setiap baris berakhir dengan karakter baris baru.
  4. Satu-satunya karakter dalam string input adalah "+", "-", "|", "", dan "\ n" (baris baru), dan string output Anda harus mengikuti aturan yang sama, dengan penambahan "=" dan "sebanyak mungkin karakter.
  5. Secara opsional, Anda dapat memiliki satu baris baru di akhir baris terakhir.
  6. Kotak ASCII terkecil yang perlu Anda tangani adalah contoh kiri atas. Setiap kotak ASCII akan memiliki tepat 4 "+", tepat di sudutnya.
  7. Anda perlu menangani kotak ukuran m x nuntuk bilangan bulat apa pun m,nsehingga 2<=m,n<256(ukuran string sebesar mungkin 255*(255+1))
  8. Anda dapat menganggap Anda akan selalu mendapatkan satu kotak ASCII yang valid sebagai input.
Melon Fricative
sumber
Saya pikir Anda lupa untuk menambahkan "karakter yang mungkin dalam output pada angka 4 dari Detail Peraturan. Edit: Bisakah kita menganggap input tidak memiliki garis kosong?
Theraot
Contoh 1x6 itu funky, mengapa meledak keluar? Saya pikir salah satu dari mereka ||dalam contoh itu harus menjadi "atau sesuatu ...
Magic Octopus Mm
@caruscomputing sama dengan contoh kiri bawah, dinding bergerak melalui satu sama lain (sehingga volume kotak negatif) - aturan 4 dan 5.
Lyth
@Lthth seharusnya masih ada "? Saya kira "hanya muncul pada 3-lebar atau lebih besar?
Magic Gurita Guci
@carusocomputing Pertimbangkan ini: Kemana perginya "? Di sebelah kiri, atau di sebelah kanan? Tidak bisa keduanya, tetapi tidak bisa karena hasilnya simetris.
HyperNeutrino

Jawaban:

15

Python 2 , 591 555 545 527 525 496 436 351 334 333 303 byte

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)

Cobalah online!

EDIT : Metode lama saya pertama kali meledak bagian atas dan bawah, dan kemudian kiri dan kanan. Sebagai gantinya, kita bisa meledak atas, memutar 90 derajat, dan melakukannya 4 kali. Juga, saya menggunakan kode yang user-friendly, yang ini membutuhkan input dalam bentuk [['+', '-', '-', '-', '-', '-', '+'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['|', ' ', ' ', ' ', ' ', ' ', '|'], ['+', '-', '-', '-', '-', '-', '+']]yang jelek tapi lebih pendek untuk program: P (Terima kasih kepada Phoenix untuk menangkap itu)

Penghargaan untuk Leaky Nun untuk kode tajuk di tautan TIO yang digunakan untuk mengubah input yang dapat dibaca manusia menjadi input yang dapat dibaca komputer.

-85 byte berkat Leaky Nun!
-17 byte dengan beralih dari atas-ledakan ke kiri-ledakan yang memungkinkan seluruh baris disimpan ke dalam variabel dan dimodifikasi. Terima kasih kepada Leaky Nun untuk sarannya!
-1 byte dengan mengalihkan berbagai hal untuk menghapus spasi.
-30 byte terima kasih untuk Leaky Nun!

HyperNeutrino
sumber
Tetapkan s[0]dan S[0]ke variabel untuk menyimpan beberapa byte
caird coinheringaahing
@Ilikemydog Oh, benar. Terima kasih!
HyperNeutrino
Anda dapat mengganti p=s[0]dan P=S[0]dengan p=z(s[0])dan P=z(S[0]), masing-masing, lalu mengganti semua kemunculan z(p)dengan pdan semua z(P)dengan Puntuk menghemat 18 byte.
R. Kap
Anda juga dapat mengganti (z(s)-1)/2-pdengan z(s)/2-.5-pdan (p-1)/2-z(s)dengan p/2-.5-z(s)untuk menyimpan 2 byte lebih banyak.
R. Kap
@ R. Kap Oh, baiklah. Terima kasih atas kedua sarannya!
HyperNeutrino
1

C (dentang) , 693 byte

Baris baru ditambahkan untuk dibaca. Dua yang pertama diperlukan tetapi sisanya tidak.

#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++);
}

Terima kasih atas tantangannya! Itu cukup rumit tetapi saya masih bersenang-senang.

Ini mengambil input sebagai argumen baris perintah dan output ke STDOUT string multi-line dari kotak meledak. Seperti biasa, tips golf sangat dihargai.

Cobalah online!

R. Kap
sumber