Segi Enam Tertanam!

18

Tugas Anda: diberi bilangan bulat n, buat pola segi enam tertanam mengikuti aturan di bawah ini, hingga kedalaman ke-n.

Hexagon yang disematkan memiliki bentuk dasar ini: ( n=0)

 __      
/  \
\__/

Segi Enam Tertanam n=1dan n=2:

  ____    
 /  \ \
/\__/  \
\      /
 \____/

    ________    
   /  \ \   \
  /\__/  \   \
 /\      /    \
/  \____/      \
\              /
 \            /
  \          /
   \________/

Panjang setiap sisi adalah 2 kali panjang sisi yang sama pada kedalaman sebelumnya dua kali. Sisi atas dan bawah panjangnya 2 karakter, kapan n=0dan sisanya mulai panjang 1 karakter. Panjang sisi non atas-bawah harus 2^npanjang ( OEIS: A000079 ) dan sisi atas dan bawah harus mengikuti aturan 2^(n+1)(OEIS yang sama).

Segi enam saat ini diindeks 0, Anda dapat memilih untuk menggunakan 1-diindeks jika Anda mau.

Ini , jadi jawaban terpendek menang!

Kamerad SparklePony
sumber
@LuisMendo Oke, saya akan mengganti namanya.
Kamerad SparklePony
Mungkin sulit menangani input besar (mis. 64). Apakah ada batasan untuk n?
Matius Roh
@SIGSEGV Tidak ada batasan untuk n.
Kamerad SparklePony
1
Akan terhibur melihat jawaban dalam Hexagony :))
Tn. Xcoder
1
Heh, grafik penyu dari pengajuan kurva Koch saya bisa melakukan ini juga (hanya fungsi pertama yang berubah). Pasti terlalu lama untuk ini :)
Ørjan Johansen

Jawaban:

10

Arang , 40 29 byte

11 byte disimpan berkat @Neil dengan mengubah loop sementara menjadi for-loop di antara trik lainnya

FN«AX²ιβ×__β↓↘β←↙β↑←×__β↖β→↗β

Cobalah online!

Penjelasan (kedaluwarsa)

Program ini dimulai dengan menghasilkan hexagon terbesar, dan kemudian melakukan yang lebih kecil satu-per-satu dalam loop sementara (1-diindeks). Untuk referensi, αadalah nomor input, βadalah variabel yang berisi 2^(α-1)dan ιmerupakan variabel iterasi dalam loop.

Nα                        # Take input and store in α
Wα«                       # While α do:
 ×_X²ι                    #  Write "_"*(2**ι); this forms the top edge of the hexagon
 ↓                         #  Go down
 AX²⁻ι¹β                 #  Assign 2**(ι-1) to β
 ↘β←                       #  Write \ β times in a SE direction (top right edge) and then go left
 ↙β↑                       #  Write / β times in a SW direction (bottom right edge) and then go up
 ←×_X²ι                   #  Write the bottom edge
 ↖β→↗β                    #  Just like before, write the top and bottom left edges
 A⁻α¹α                    #  Decrement α
                          # Now the pointer is at the top left corner of the hexagon,
                          # from where the other smaller hexagons will soon be generated
Kritixi Lithos
sumber
Saya perhatikan tidak ada "Halo, Dunia!" program untuk Arang belum. Anda harus menambahkannya.
mbomb007
@ mbomb007 Bukankah itu hanya duplikat dari sepele "bahasa ini mencetak file sumbernya jika tidak mengandung perintah" jawab?
Neil
Saya menyimpan beberapa byte ketika saya menyadari bahwa ×_X²ιitu sama dengan ×__β, dan beberapa byte lagi dengan mengubah Anda menjadi , yang juga menghindari keharusan untuk menyimpan nomor input. Cobalah online! .
Neil
@Neil Terima kasih, itu cukup rapi :)
Kritixi Lithos
5

Haskell , 230 217 207 byte

EDIT:

  • -13 byte: @xnor melihat bahwa saya #bisa saja max.
  • -10 byte: Dan juga itu zipWithdan pbisa digabung menjadi ?operator, dan saya akan (entah bagaimana!) Diimplementasikan kembali replicate.

mmengambil Integerdan mengembalikan a String.

m n=unlines.foldr1 o$((2^n)&).(2^)<$>[0..n]
l&t|a<-c[l,2*t]" _",b<-[c[l-i,1,2*t+2*i-2,1,l-i]" / \\ "|i<-[1..t]]=a:b++r(r<$>o[a]b)
c=(concat.).z replicate
o=max?' '?""
f?e=z f.(++repeat e)
r=reverse
z=zipWith

Cobalah online!

Bagaimana itu bekerja

  • madalah fungsi utama. Ini digunakan &untuk menghasilkan segi enam dengan bantalan yang tepat, lalu melipatnya bersama o.
  • l&tmenghasilkan segi enam kecil panjang sisi t, empuk di dalam yang besar panjang sisi l, sebagai daftar Stringgaris.
    • a adalah garis atas segi enam, dengan garis bawah.
    • badalah daftar garis lain di bagian atas segi enam. Garis-garis bdipusatkan di padding, yang persegi panjang; ini memungkinkan langkah selanjutnya untuk bekerja.
    • Setengah bagian bawah segi enam adilapis di atas bdengan o, lalu dibalik (urutan kedua garis dan di dalam setiap baris).
  • cmengambil dua argumen, daftar panjang dan string, dan menghasilkan string yang memiliki banyak salinan dari masing-masing karakter dalam aslinya sebagai panjang yang sesuai, misalnya c[1,3,2]"abc" == "abbbcc". Ini digunakan &untuk menghasilkan garis.
  • o mengambil dua argumen yang mewakili gambar sebagai daftar garis, dan menayangkan yang pertama, lebih kecil di atas yang kedua.
    • Ini digunakan baik untuk menggabungkan segi enam dan untuk menambahkan bagian bawah ke setiap segi enam.
    • Ini pada dasarnya bekerja dengan menggunakan ?dua kali untuk melapisi gambar pertama dengan banyak ruang tak terbatas baik ke bawah dan ke kanan, kemudian zipping bersama karakter yang sesuai dengan max, yang memilih karakter non-spasi jika ada.
  • (f?e)l mmembalut daftar ldengan menambahkan banyak elemen 'e', ​​kemudian ritsleting daftar yang dihasilkan dan daftar mdengan ffungsi.
Ørjan Johansen
sumber
1
Solusi bagus! Saya pikir (#)bisa max.
xnor
1
Zipping yang dapat dikombinasikan dengan pke save bytes: o=max?' '?"";f?e=z f.(++repeat e). Mungkin pointfree lebih pendek.
xnor
2
(\n->(<$[1..n]))adalah replicate.
xnor
@ xnor replicate? Nah, itu memalukan. Aku terlalu terbiasa <$[1..n]atau [1..n]>>hampir selalu menang. Namun, saya tidak melihat bagaimana mempersingkat ?lebih lanjut. Saya sudah mencoba membuat ppointfree dan ++hanya ada di tempat yang salah, meledakkan hal-hal dengan flip.
Ørjan Johansen
3

JavaScript (ES6), 258 byte

f=(n,s=` `.repeat(1<<n),p=(n?f(n-1):`


`).replace(/(.*)\n/g,s+`$1 `+s)+s,t=`_`.repeat(2<<n))=>(s+t+s+`
`+s.replace(/ /g,"$'/$'$'  $`$`$`$`\\$'\n")).replace(/ /g,(c,i)=>p[i+(1<<n>>1)])+s.replace(/ /g,"$`\\$`$`  $'$'$'$'/$`\n").replace(/ +\/( *)\n$/,t+`/$1
`)
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Penjelasan: Untuk segi enam setelah yang pertama, segi enam sebelumnya pertama kali dihasilkan dan empuk di setiap sisi (ini bergantung pada output menjadi persegi panjang). (Untuk heading pertama, beberapa dummy padding dibuat.) Sisi atas dan atas segi enam dihasilkan, dan semua ruang digabung dengan segi enam sebelumnya. (Ada beberapa tipu daya untuk membuat hexagon berbaris; ini akan lebih mudah jika margin tambahan diizinkan.) Sisi bawah hexagon dihasilkan secara analog ke sisi atas, dan bagian bawah hexagon kemudian diisi. Kehati-hatian harus diambil untuk mengembalikan output persegi panjang, termasuk baris baru, agar rekursi dapat bekerja.

Neil
sumber
Jadi, Anda menunjukkan bahwa ini, yang Teflon, dan Pizza Deep Dish, semua konstruksi yang benar-benar mirip? Itu agak rapi.
AdmBorkBork
1
@ AdmBorkBork Saya punya beberapa jawaban lain yang melakukan itu; mereka diagonal /s populer dalam seni ASCII dan replacemetode ini adalah cara yang relatif murah untuk menghasilkan mereka dalam JavaScript.
Neil
1<<n>>1: Nice symmetry ;-)
Luke
@ Lukas saya bisa mengubah variabel menjadi, katakanlah, vtetapi sayangnya 1tidak simetris di salah satu font biasa saya.
Neil
2

PHP, 337 Bytes

0 Pengindeksan

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v));for(;1+$c;$c--)for($i=0;$i<$e=2**$c*2+1;$i++){$z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1;$h[$i]=substr_replace($h[$i],$s=str_pad(!$y?$z|$x?"\\":"":"/",$e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),$z|!$i?"_":" ").(!$y?$z|$x?"/":"":"\\"),$v-$z-$y*$i-$x*($e-$i),strlen($s));}echo join("\n",$h);

Cobalah online!

Diperluas

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v)); # fill array with maximal width
for(;1+$c;$c--)  # greatest hexagon to lowest
for($i=0;$i<$e=2**$c*2+1;$i++){ # loop through the rows
    $z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1; # booleans last first ad second half
    $h[$i]=substr_replace($h[$i], # replace substring
    $s=str_pad(
        $z?"\\":($y?"/":($x?"\\":"")),
        $e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),
        $z|!$i?"_":" "
        ).(!$z?!$y?$x?"/":"":"\\":"/"), # with string for smaller hexagon
    $v-$z-$y*$i-$x*($e-$i), # at offset
    strlen($s));
}
echo join("\n",$h); # Output
Jörg Hülsermann
sumber