Lipat Handuk!

19

Saya mendengar di suatu tempat bahwa satu hal yang teknologi belum bisa lakukan adalah melipat handuk 1 . Jadi sekarang tugas Anda untuk membuktikan pernyataan itu salah!

Diberikan string sebagai input, terdiri dari persegi panjang (handuk), seperti yang berikut, lipat setiap handuk menjadi dua kali dua. Sebagai contoh:

+------+    +------+        +--+
|      |    |      |        |  |
|      |    |      |        |  |
|      | -> +------+ ->     +--+
|      |    
|      |    
|      |    
+------+    

Perhatikan bahwa ketika handuk dilipat, pertama kali dilipat, kemudian dari kiri ke kanan. Program Anda juga harus meniru perilaku ini. Juga perhatikan bahwa dalam kasus uji, handuk tetap berada di tempat yang sama, tetapi dilipat.

Aturan:

  • Metode input / output standar.
  • Celah standar berlaku.
  • Input dan output harus berupa string.
  • Keluaran apa pun yang tertinggal tidak apa-apa, asalkan handuk berada di tempat yang tepat relatif satu sama lain.
  • Anda dapat mengasumsikan bahwa panjang setiap sisi handuk akan selalu habis dibagi 2.
  • Handuk yang dilewatkan sebagai input akan selalu berbentuk persegi panjang.
  • Handuk akan selalu dipisahkan - namun, mereka dapat dipisahkan dengan jumlah yang bervariasi.

  • , jadi kode terpendek menang!

Kasus uji:

Input:
+------+
|      |
|      |
|      |
|      |
|      |
|      |
+------+
Output:
    +--+
    |  |
    |  |
    +--+




Input:
+--+ +--+ +--+
|  | |  | |  |
|  | |  | |  |
+--+ +--+ +--+

Output:
  ++   ++   ++
  ++   ++   ++


Input:
+----+
|    |
|    |
|    |
|    | ++
+----+ ++

Output:

   +-+
   | |
   +-+

        +

Input:
+--+
+--+     ++
         ||
         ||
         ++
Output:
  ++
          +
          +

1: Ini telah dibantah oleh Geobits dan Laikoni. Namun, saya memang pernah mendengarnya di suatu tempat.

Kamerad SparklePony
sumber
Mengapa downvote? Jika ada sesuatu yang bisa diperbaiki, tolong beritahu saya.
Kamerad SparklePony
@Laikoni sepertinya teknologi DAPAT melakukan apa pun :-)
Tn. Xcoder
@LuisMendo Diedit, akan selalu ada ruang di antara handuk.
Kamerad SparklePony
Apakah handuk akan selalu berbaris horizontal? Maksud saya tidak akan ada handuk di bawah handuk lainnya?
Dead Possum

Jawaban:

5

Retina , 245 byte

m1+`^((.)*(?!\+ )[+|]([- ])*[+|].*¶(?<-2>.)*)([+|][- ]*[+|])
$1$.4$* 
m+`^((.)*) ( *) (.*¶(?<-2>.)*)(?(2)(?!))\|\3\|
$1|$3|$4 $3 
m+`^((.)*)\|( *)\|(?=.*¶(?<-2>.)*(?(2)(?!)) )
$1+$.3$*-+
([+|])\1
 $1
(?!\+ )([+|])([- ])\2(\2*)\3\1
$.3$*   $1$3$1

Cobalah online!

Catatan: beberapa garis berakhir dengan spasi. Penjelasan:

m1+`                    Repeatedly search from the beginning of input
    ^((.)*              Optional indentation
      (?!\+ )           Towel does not start with a plus and a space
      [+|]([- ])*[+|]   A row of towel
      .*¶               Rest of the line
      (?<-2>.)*         Some indentation on the next line
     )
     ([+|][- ]*[+|])    Another row of towel
$1$.4$*                 Replace the second row with blanks

Hapus setiap garis lain dari setiap handuk (ini berfungsi karena semua handuk memiliki ketinggian lebih),

m+`             Repeatedly search
   ^((.)*)      Optional indentation
    ( *)        Find some space
    (.*¶        Rest of the line
     (?<-2>.)*) Matching indentation on the next line
    (?(2)(?!))  Ensure that the indentation exactly matches
    \|\3\|      Piece of towel
$1|$3|$4 $3     Swap the piece into the space above

geser semua potongan handuk yang terlepas ke atas,

m+`                 Repeatedly search
   ^((.)*)          Optional indentation
    \|( *)\|        Piece of towel
    (?=             Followed by
       .*¶          Rest of the line
       (?<-2>.)*    Matching indentation on the next line
       (?(2)(?!))   Ensure that the indentation exactly matches
        )           Nothing on the next line
$1+$.3$*-+          Change the piece into a towel bottom

dan perbaiki bagian bawah handuk, secara efektif melipatnya.

([+|])\1    Match a row of towel of width 2, which is just ++ or ||
 $1         Change the first column to a space, which folds it

Lipat handuk lebar 2 ke kanan.

(?!\+ )     Towel does not start with a plus and a space
([+|])      Start with a + or a |
([- ])\2    Then at least two -s or spaces
(\2*)\3     Then an even number of -s or spaces
\1          Then another + or |
$.3$*       Replace the left half with spaces
$1$3$1      Replace the first character of the right half

Lipat handuk yang tersisa ke kanan.

Neil
sumber
Saya akan tertarik pada penjelasan yang lebih rinci tentang cara kerja regex
Kritixi Lithos
@KritixiLithos Sesuatu seperti itu, atau ada sesuatu yang spesifik?
Neil
Ya terima kasih. Dan apakah saya benar dengan menganggap bahwa itu <-2>adalah kelompok penyeimbang .NET?
Kritixi Lithos
@KritixiLithos Menggunakannya: (?<-2>.)*muncul tangkapan setiap kali, jadi tidak dapat mengulangi lebih banyak dari yang (.)*dilakukan, sementara (?(2)(?!))memeriksa bahwa tidak ada tangkapan yang tersisa, sehingga ia mengulangi jumlah yang sama kali.
Neil
3

Paket Oktaf dengan Gambar , 277 272 byte

function x=f(x)
[i,j,v]=find(bwlabel(x-32));a=@(w)accumarray(v,w,[],@max);r=-a(-i);R=a(i);s=-a(-j);S=a(j);x(:)=32;for k =1:nnz(r)
u=(r(k)+R(k)-1)/2;v=(s(k)+S(k)+1)/2;p=v:S(k);x(r(k),p)=45;x(u,p)=45;q=r(k):u;x(q,v)=124;x(q,S(k))=124;x(u,[v S(k)])=43;x(r(k),[v S(k)])=43;end

Input dan output adalah array char 2D.

Cobalah online! Atau verifikasi semua kasus uji: 1 , 2 , 3 , 4 . (Perhatikan bahwa endfunctiondalam kasus uji hanya diperlukan untuk memisahkan fungsi dari kode berikutnya. Tidak perlu jika fungsi disimpan dalam file sendiri.)

Versi dan penjelasan yang mudah dibaca

function x = f(x)
[i,j,v] = find(bwlabel(x-32)); % make background equal to 0 by subtracting 32.
% Then label each connected component (i.e. towel) with a unique integer
% Then get row indices (i) and column indices (j) of nonzero values (v)
a = @(w)accumarray(v,w,[],@max); % helper function. Gives the maximum of w for
% each group given by an integer label in v
r = -a(-i); % upper coordinate of each towel (minimum row index)
R = a(i); % lower coordinate of each towel (maximum row index)
s = -a(-j); % left coordinate of each towel (minimum column index)
S = a(j); % right coordinate of each towel (maximum column index)
x(:) = 32; % remove all towels: fill x with spaces
for k = 1:nnz(r) % for each original towel: create the new, folded towel 
    u = (r(k)+R(k)-1)/2; % new lower coordinate
    v = s(k)+S(k)+1)/2; % new left coordinate
    p = v:S(k); % column indices of horizontal edges
    x(r(k),p) = 45; % fill upper horizontal edge with '-'
    x(u,p) = 45; % fill lower horizontal edge with '-'
    q = r(k):u; % row indices of vertical edges
    x(q,v) = 124; % fill left vertical edge with '|'
    x(q,S(k)) = 124; % fill right vertical edge with '|'
    x(u,[v S(k)]) = 43; % fill lower corners with '+'
    x(r(k),[v S(k)]) = 43; % fill upper corners with '+'
end
Luis Mendo
sumber