Perbaikan rumah untuk Minotaur

42

Perbaikan rumah untuk Minotaur

Labirin Kreta cukup mudah untuk menggambar. Mulai saja dengan bentuk simetris (warna merah di sini). Mari kita sebut semua titik akhir dari garis-garis 'simpul'. Kemudian Anda mulai menggambar lengkungan (hitam): Yang pertama alway dimulai di simpul tengah atas dan menghubungkan ke simpul di sebelahnya di sisi kanan, kemudian dua simpul yang paling dekat dengan lengkungan sebelumnya terhubung. Ini diulang sampai semua node tercakup.

gif

Sekarang kita dapat menggeneralisasi konsep ini: Kita dapat dengan mudah menghasilkan pola awal baru dengan menambahkan lebih banyak Lbentuk. Saya menyebutkan bentuk awal sebagai berikut:

gelar

Pola paling kiri akan menghasilkan labirin Kreta derajat 0 . Yang berikutnya akan membuat labirin Kreta derajat 1 (yang asli) dll.

Tugas

Diberikan bilangan bulat negatif n, program Anda harus menampilkan representasi ascii dari labirin tingkat Kreta n, yang ditunjukkan dalam contoh berikut. Mengejar spasi / baris baru tidak masalah. Anda harus memasukkan penjelasan singkat tentang cara kerja kode Anda.

Contohnya

Output untuk labirin Kreta asli (derajat 1) adalah sebagai berikut:

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

Pola awal:

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

Labirin Kreta derajat 0 akan terlihat seperti ini:

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

Pola awal:

+ | +
--+--
+ | +
cacat
sumber

Jawaban:

10

Perl 5, 349 byte

say$p="| "x$_,"+","-"x(16*$n-4*$_+13),"+ $p"for 0..4*($n=pop)+3;say$p="| "x(3*$n+2),"+ | ","| "x2x$n,"+ $p|";$p=~s/..//,$q="-"x(4*$_-1),say"$p+$q+ ","| "x(2*$n-2*$_+1),"+$q+ $p|"for 1..$n;$p=~s/..//;say$p,("+---"."-"x4x$n)x2,"+ $p|";$p=~s/..//,$q="-"x(4*$n+3)."-"x4x$_,say"$p+$q+ | ","| "x2x($n-abs$_),"+$q+ $p|"for-$n..$n;say" "x(8*$n+6),"+----$q+"

(Lewati n sebagai argumen baris perintah.)

Menghitung garis demi garis labirin dalam enam bagian:

  • 4n + 4 baris pertama,
  • baris berikutnya (satu-satunya baris tanpa -),
  • selanjutnya n baris,
  • baris berikutnya (garis di tengah pola awal),
  • 2n + 1 baris berikutnya,
  • baris terakhir (garis dengan spasi utama).
Anders Kaseorg
sumber
6

Python 3.5, 703 695 676 648 587 581 542 535 500 486 462 431 423 411 byte:

( Terima kasih kepada @ flawr untuk saran tentang menghemat 55 byte (486 -> 431)! )

def j(r):R=range;Z=zip;B=r+r+2;P,M='+-';X='| ';q=[*Z(R(0,B-1,2),R(B-1,0,-2))];L=r+1;A=2+r;print('\n'.join([X*w+P+M*v+P+' |'*w for v,w in Z(R(4*L*4-3,0,-4),R(4*L))]+[X*g+P*o+M*k+u+M*k+P*o+' |'*-~g for g,o,k,u in Z([*R(4*L-A,0,-1),*R(4*L-A)],[0]+[1]*(3*r+2),[0,*R(1,4*L,2),*R(4*L+1,11*r,2)],[M*y+'+ '+X*b+P+M*y for y,b in q]+[M*B+P+M*B]+[M*y+'+ '+X*b+P+M*y for y,b in q[::-1]+q[1:]])]+[' '*(8*r+6)+P+M*(8*r+7)+P]))

Tidak terlalu banyak pesaing untuk judul, tapi saya masih mencobanya, dan itu bekerja dengan sempurna. Saya akan mencoba untuk mempersingkat lebih dari waktu di mana saya bisa, tetapi untuk sekarang, saya menyukainya dan tidak bisa lebih bahagia.

Cobalah online! (Ideone) (Mungkin terlihat sedikit berbeda di sini karena keterbatasan kompiler online yang jelas. Namun, masih sangat sama.)

Penjelasan:

Untuk keperluan penjelasan ini, mari kita asumsikan bahwa fungsi di atas dijalankan dengan input,, rsama dengan 1. Yang sedang berkata, pada dasarnya apa yang terjadi, langkah demi langkah, adalah ...

  1. q=[*Z(R(0,B-1,2),R(B-1,0,-2))]

    Objek zip,, qdibuat dengan 2 objek jangkauan, satu terdiri dari setiap bilangan bulat kedua dalam rentang 0=>r+r+1dan lainnya terdiri dari setiap bilangan bulat kedua dalam rentang r+r+1=>0. Ini karena setiap pola awal labirin Kreta dari tingkat tertentu akan selalu memiliki angka genap -di setiap baris. Misalnya, untuk labirin tingkat kretan 1, r+r+1sama dengan 3, dan dengan demikian, polanya akan selalu dimulai dengan 0tanda hubung, diikuti oleh garis lain dengan tanda hubung 4(2 + 2). Objek zip ini akan digunakan untuk r+1garis pertama dari pola labirin.

    Catatan: Satu- satunya alasan qadalah daftar dan terpisah dari yang lain adalah karena qdireferensikan beberapa kali dan disubkripsikan, dan untuk menyimpan banyak pengulangan dan memungkinkan berlangganan, saya cukup membuat objek zip qdalam bentuk daftar.

  2. print('\n'.join([X*w+P+M*v+P+' |'*w for v,w in Z(R(4*L*4-3,0,-4),R(4*L))]+[X*g+P*o+M*k+u+M*k+P*o+' |'*-~g for g,o,k,u in Z([*R(4*L-A,0,-1),*R(4*L-A)],[0]+[1]*(3*r+2),[0,*R(1,4*L,2),*R(4*L+1,11*r,2)],[M*y+'+ '+X*b+P+M*y for y,b in q]+[M*B+P+M*B]+[M*y+'+ '+X*b+P+M*y for y,b in q[::-1]+q[1:]])]+[' '*(8*r+6)+P+M*(8*r+7)+P]))

    Ini adalah langkah terakhir, di mana labirin dibangun dan disatukan. Di sini, tiga daftar, yang pertama terdiri dari 4*r+1garis-garis atas labirin, yang kedua terdiri dari 3*r+3garis-garis tengah labirin, dan daftar terakhir yang terdiri dari baris paling terakhir dari labirin bergabung bersama, dengan jeda baris ( \n) menjadi satu string panjang. Akhirnya, string besar yang terdiri dari seluruh labirin ini dicetak. Mari kita selami lebih dalam isi 2 daftar dan 1 string ini:

    • Daftar 1, di mana objek zip lain digunakan dalam pemahaman daftar untuk membuat setiap baris satu per satu, dengan memimpin |atau +simbol, jumlah garis putus-putus dalam rentang 0=>4*(r+1), trailing |atau +simbol, dan kemudian baris baru ( \n). Dalam kasus 1labirin derajat , daftar ini mengembalikan:

      +-----------------------------+
      | +-------------------------+ |
      | | +---------------------+ | |
      | | | +-----------------+ | | |
      | | | | +-------------+ | | | |
      | | | | | +---------+ | | | | |
      | | | | | | +-----+ | | | | | |
      | | | | | | | +-+ | | | | | | |
      
    • Daftar ke-2, yang terdiri dari objek zip yang berisi 4 daftar, dan masing-masing daftar sesuai dengan jumlah |simbol memimpin / trailing , jumlah +simbol, jumlah tanda hubung, dan akhirnya, daftar terakhir, yang berisi r+1baris pertama dari pola dibuat sesuai dengan objek zip q, garis di tengah pola (yang tanpa |), dan r+2garis terakhir dari pola simetris. Dalam kasus khusus ini, daftar terakhir yang digunakan dalam objek zip daftar ini akan kembali:

      + | | | +
      --+ | +--
      ----+----
      --+ | +-- 
      + | | | + 
      --+ | +--  <- Last line created especially for use in the middle of the labyrinth itself.
      

      Dan karena itu, dalam kasus labirin 1 derajat, seluruh daftar ini akan kembali:

      | | | | | + | | | + | | | | | |
      | | | | +---+ | +---+ | | | | |
      | | | +-------+-------+ | | | |
      | | +-------+ | +-------+ | | |
      | +-------+ | | | +-------+ | |
      +-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
      
    • Daftar terakhir ini, di mana baris terakhir dibuat. Di sini, panjang segmen pertama (yang sebelum spasi pertama) dari baris terakhir daftar Pjumlah spasi dibuat. Kemudian, panjang segmen terakhir (segmen akhir) dari garis yang sama + 4 jumlah garis ditambahkan, yang semuanya didahului dan diikuti oleh +simbol tunggal . Dalam kasus labirin derajat 1, daftar terakhir ini mengembalikan:

                    +---------------+
      

    Setelah menggabungkan semua ini, langkah ini akhirnya mengembalikan labirin yang lengkap. Dalam kasus labirin 1 derajat, akhirnya akan mengembalikan ini:

    +-----------------------------+
    | +-------------------------+ |
    | | +---------------------+ | |
    | | | +-----------------+ | | |
    | | | | +-------------+ | | | |
    | | | | | +---------+ | | | | |
    | | | | | | +-----+ | | | | | |
    | | | | | | | +-+ | | | | | | |
    | | | | | + | | | + | | | | | |
    | | | | +---+ | +---+ | | | | |
    | | | +-------+-------+ | | | |
    | | +-------+ | +-------+ | | |
    | +-------+ | | | +-------+ | |
    +-----------+ | +-----------+ |
                  +---------------+
    
R. Kap
sumber
1
Bisakah Anda pertama mendefinisikan R=rangeatau sesuatu seperti itu? Sama untuk P='+'?
flawr
1
Saya pikir Anda harus mengambil kesempatan emas untuk mengatakanfor g,o,k,u in Z
Sherlock9
@ Sherlock9 Haha! Ide bagus! Ditambahkan. :)
R. Kap