Jadikan aku pohon Natal yang terbalik!

15

Tantangan

Kita semua tahu tentang pohon Natal yang normal - tetapi bagaimana dengan pohon Natal yang terbalik ! Ini adalah tantangan bertema Natal yang cukup mudah. Tujuan dari tantangan ini adalah menjadikan saya pohon Natal terbalik ASCII. Berikut adalah aturan untuk tantangan ini:

  1. Terima bilangan bulat ganjil dan positif. Anda dapat menganggap itu akan selalu antara 7dan 51.
  2. Pangkal pohon akan dibuat dari karakter:

    ___
    \ /
     |
    
  3. Bagian atas pohon (bintang), akan terdiri dari satu *.

  4. Setiap baris pohon akan dibangun menggunakan format di <?>mana ?sejumlah -s. Misalnya, jika membuat garis panjang 5, garis itu seharusnya <--->. Atau jika membuat garis panjang 8, garis itu seharusnya <------>.

  5. Inilah bagaimana tubuh pohon seharusnya dibangun:

    1. Ambil angka ganjil yang ndiberikan sebagai input, dan buat garis pohon sepanjang itu.

    2. Kurangi 4dari ndan membuat garis pohon yang panjang.

    3. Kurangi 2dari ndan membuat garis pohon yang panjang.

    4. Pengurangan noleh 2. Setelah itu, kecuali nsama dengan5 , kembali ke langkah 2.

  6. Basis (lihat langkah 2.) bintang (lihat langkah 3.) dan setiap baris pohon (lihat langkah 4. dan 5.) semuanya harus dipusatkan menggunakan input nomor ganjil asli (lihat langkah 1.) sebagai maksimum lebar.

Contoh / Kasus Uji

odd number inputed: 7
  ___
  \ /
   |
<----->      line length -> 7
  <->        line length -> 7 - 4 = 3
 <--->       line length -> 7 - 2 = 5
   *


odd number inputed: 13
     ___
     \ /
      |
<----------->      line length -> 13
  <------->        line length -> 13 - 4 = 9
 <--------->       line length -> 13 - 2 = 11
   <----->         line length -> 11 - 4 = 7
  <------->        line length -> 11 - 2 = 9
    <--->          line length -> 9 - 4 = 5
   <----->         line length -> 9 - 2 = 7
     <->           line length -> 7 - 4 = 3 
    <--->          line length -> 7 - 2 = 5
      *


odd number inputed: 9
   ___
   \ /
    |
<------->      line length -> 9
  <--->        line length -> 9 - 4 = 5
 <----->       line length -> 9 - 2 = 7
   <->         line length -> 7 - 4 = 3
  <--->        line length -> 7 - 2 = 5
    *


odd number inputed: 17
       ___
       \ /
        |
<--------------->      line length -> 17
  <----------->        line length -> 17 - 4 = 13
 <------------->       line length -> 17 - 2 = 15
   <--------->         line length -> 15 - 4 = 11
  <----------->        line length -> 15 - 2 = 13
    <------->          line length -> 13 - 4 = 9
   <--------->         line length -> 13 - 2 = 11
     <----->           line length -> 11 - 4 = 7
    <------->          line length -> 11 - 2 = 9
      <--->            line length -> 9 - 4 = 5
     <----->           line length -> 9 - 2 = 7
       <->             line length -> 7 - 4 = 3
      <--->            line length -> 7 - 2 = 5
        *    

Aturan

Christian Dean
sumber
3
Melihat bahwa input dijamin menjadi angka ganjil, dapatkah kita mengambil indeksnya dalam urutan ganjil?
FlipTack
Juga - repeat the above steps until the odd number minus 2 equals 5- pada input pertama, angka ganjil adalah 7, dan 7-2 = 5, oleh karena itu pohon harus berakhir secara instan (saya tahu apa yang Anda maksud, tetapi perlu
pengulangan kata
@FlipTack Saya tidak yakin apa yang Anda maksud. Jika angka ganjil adalah 7, input minimum, pertama - tama Anda harus membuat tiga garis pohon (sub-langkah .1.1, .1.2, .1.3), kemudian kurangi 2dari angka ganjil dan uji jika jumlahnya sama 5. Instruksi untuk memeriksa apakah "angka ganjil minus 2 sama dengan 5" adalah pada akhirnya, tiga langkah lainnya harus dilakukan terlebih dahulu. Tetapi untuk menjawab komentar pertama Anda, itu akan baik-baik saja.
Christian Dean
1
@FlipTack Saya pikir dia bertanya apakah Anda harus menerima 7sebagai input atau jika Anda dapat menerima 4, seperti pada nomor ganjil keempat (atau 3jika itu 0-diindeks).
DonielF
4
Dari judul: "Oke, sekarang Anda pohon Natal yang terbalik."
dkudriavtsev

Jawaban:

10

Python 3 , 127 121 105 103 100 98 byte

Ini adalah fungsi lambda tanpa nama yang mengembalikan daftar baris:

lambda o:[s.center(o)for s in['___','\ /','|',*[f'<{"-"*(o-i+2-i%2*3)}>'for i in range(4,o)],'*']]

Cobalah online!

Bagian utama dari jawaban ini adalah (o-i+2-i%2*3) , yang menghitung jumlah tanda hubung yang harus dimiliki pada sebuah garis. Sisa jawabannya hanyalah dengan mengubahnya menjadi ASCII-art yang diinginkan.

Terima kasih banyak kepada Tn. Xcoder , karena mencukur 6 byte, dan mendiskusikan golf dengan saya dalam obrolan.

Terima kasih juga kepada Lynn untuk memperhatikan hal 3*(i%2)itu i%2*3, 2 byte lebih pendek!

FlipTack
sumber
2
Setiap kali saya memposting jawaban Python, tidak peduli waktu hari atau lokasi saat ini, @ Mr.Xcoder punya golf untuk diberikan :)
FlipTack
Nah , ini dengan mudah mengalahkan solusi 250 byte + Python saya. Pekerjaan yang baik! +1
Christian Dean
o-i+2-i%2*3menghemat dua byte.
Lynn
@ Lynn Tempat yang bagus, diperbarui.
FlipTack
7

C, 163 byte

#define P;printf(
i;g(l){P"%*c",1+i-l--/2,60);for(;--l P"-"))P">\n");}f(n){i=n/2 P"%*c__\n%*c /\n%*c|\n",i,95,i,92,i,32);for(g(n);n>5;g(n-=2))g(n-4)P" %*c",i,42);}

Cobalah online!

Belum dibuka:

#define P;printf(

i;
g(l)
{
    P"%*c", 1+i-l--/2, 60);
    for (; --l P"-"))
    P">\n");
}

f(n)
{
    i=n/2
    P"%*c__\n%*c /\n%*c|\n", i, 95, i, 92, i, 32);

    for(g(n); n>5; g(n-=2))
        g(n-4)

    P" %*c", i, 42);
}
Steadybox
sumber
6

Proton , 83 byte

Terima kasih kepada FlipTack untuk menyimpan 4 byte, dan untuk berkolaborasi dalam obrolan (kami benar-benar membentuk tim yang hebat). Secara tidak langsung menyimpan 2 byte berkat Lynn .

o=>[s.center(o)for s:['___','\ /','|']+['<'+"-"*(o-i+2-i%2*3)+'>'for i:4..o]+['*']]

Cobalah online!

Tuan Xcoder
sumber
5

Arang , 28 byte

__⸿ /⸿|F⮌…¹⊘N«⸿⊕ι>⸿⊖ι>»‖B← *

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

__⸿ /⸿|

Cetak alasnya.

F⮌…¹⊘N«

Ulangi dari setengah jumlah input menjadi 1.

⸿⊕ι>⸿⊖ι>»

Cetak dua baris, yang pertama dengan satu lebih -dari indeks lingkaran, yang kedua dengan yang lebih sedikit.

‖B←

Cermin untuk menyelesaikan pohon.

 *

Tempatkan bintang.

Neil
sumber
3

Retina , 89 byte

.+
$*->
^--
<
+`( *<)----(-+>)$
$&¶  $1$2¶ $1--$2
s`.*¶( +)<->.*
$1___¶$1\ /¶$1 |¶$&¶$1 *

Cobalah online! Penjelasan: Tahap pertama mengubah input menjadi unary dan menambahkan a >. Tahap kedua menggantikan dua -s dengan <untuk memperbaiki panjang garis. Tahap ketiga kemudian mereplikasi cabang tetapi sedikit lebih pendek setiap kali sampai cabang tidak dapat dipersingkat lebih jauh. Tahap akhir menambahkan basis dan bintang.

Neil
sumber
2

Javascript 506 byte

Versi golf:

function tree(i){const mid=(i+1)/2;const leg1=' '.repeat((mid-2))+`___
`;const leg2=' '.repeat((mid-2))+`\\ \/
`;const leg3=' '.repeat((mid-1))+`|
`;let xmasTree=leg1+leg2+leg3;for(let j=0;j<(i-4);j++){if(j%2===0){let v=j/2;let t=i-2*v-2;let body1=" ".repeat(j/2)+"<"+"-".repeat(t)+">"+`
`;xmasTree=xmasTree+body1}else{let k=1+Math.ceil(j/2);let h=i-2*k-2;let body2=' '.repeat(k)+'<'+'-'.repeat(h)+">"+`
`;xmasTree=xmasTree+body2}}
const head=' '.repeat((mid-1))+'*'
xmasTree=xmasTree+head;return xmasTree}

Versi ungolf:

function tree(i){
  const mid = (i+1)/2;
  const leg1 = ' '.repeat((mid-2)) + `___
`;
  const leg2 = ' '.repeat((mid-2)) + `\\ \/
`;
  const leg3 = ' '.repeat((mid-1)) + `|
`;
  let xmasTree = leg1 + leg2 + leg3;
  for (let j = 0; j<(i-4); j++) {
    if (j%2===0) {
      let v = j/2;
      let t = i-2*v-2;
      let body1 = " ".repeat(j/2)+"<"+"-".repeat(t) +">"+`
`;
      xmasTree = xmasTree + body1;
    } else {
      let k = 1 + Math.ceil(j/2);
      let h = i-2*k-2;
      let body2 = ' '.repeat(k)+ '<'+ '-'.repeat(h) + ">"+`
`;
      xmasTree = xmasTree + body2;
    }
  }
  const head = ' '.repeat((mid-1)) + '*'
  xmasTree = xmasTree + head;
  return xmasTree;
}

Pemakaian: console.log(tree(13)), console.log(tree(17)),

ES6 165 byte (dari teman saya)

Versi golf:

p=n=>{l=_=>console.log(`${' '.repeat((n-_.length)/2)}${_}`);t=_=>_==1?'*':'<'+'-'.repeat(_-2)+'>';x=n;l('___');l('\\ /');l('|');for(;x!==3;){l(t(x));l(t(x-4));x-=2}}

Versi ungolf:

p = n => {
  l = _ => console.log(`${' '.repeat((n-_.length)/2)}${_}`);
  t = _ => _ == 1 ? '*' : '<' + '-'.repeat(_-2)+'>';
  x = n;
  l('___');l('\\ /');l('|');
  for(;x!==3;) {
    l(t(x)); l(t(x-4));x-=2;
  }
}

Pemakaian: p(31); p(17);

NTCG
sumber
1
Anda bisa bermain golf ini banyak, dengan hanya menggunakan nama variabel 1 huruf, menghapus constkata kunci, dll
FlipTack
1

PowerShell , 131 byte

$i=2;$x="$args"..5|%{' '*($j=if($_%2){$i-2}else{($i++)})+'<'+'-'*($_-(5,2)[$_%2])+'>'};($y=' '*++$j)+"___";"$y\ /";"$y |";$x;"$y *"

Cobalah online!

Nah, ini adalah kekacauan yang tepat bagi siapa pun yang tidak fasih dalam PowerShell ... jadi, mari kita lihat seberapa baik saya bisa menjelaskan cara kerjanya.

Untuk penjelasannya, saya akan menggunakan input = 17.

Kami memulai cukup sederhana, dengan mengatur variabel pembantu $i=2dan pengaturan $xke <something>, dengan <something>mulai sebagai rentang dari input $argske bawah 5, jadi17,16,15,...,6,5 . Kisaran itu dipompa ke dalam for loop.

Setiap iterasi, kita mulai dengan menetapkan variabel pembantu $juntuk menjadi hasil ifpernyataan if($_%2){$i-2}else{($i++)},. Jika aneh $j=$i-2,, sebaliknya $j=($i++). Ini, ditambah dengan $i=2pada awalnya, memberi kita urutan 0, 2, 1, 3, 2, 4, 3, 5...yang kebetulan berhubungan persis dengan berapa banyak ruang yang kita butuhkan untuk dipertukarkan dengan garis pohon kita. ;-) Kami mengambil ' 'dan mengalikannya dengan angka itu.

Selanjutnya kita perlu cabang kita. Ini dilakukan dengan '<'ditambah bagian tengah '-'dikalikan, ditambah bagian akhirnya '>'. Perkalian dilakukan dengan mengenali bahwa -alternatif dalam suatu 2, 5, 2, 5, 2...pola berdasarkan pada nomor input $_, jadi kami memilih dari pseudo-ternary berdasarkan pada pola itu.

Untuk klarifikasi lebih lanjut, berikut adalah istilah pasangan pertama di setiap bagian:

$_ = 17 16 15 14 13 12 11 10
$j =  0  2  1  3  2  4  3  5
mid=  2  5  2  5  2  5  2  5
'-'= 15 11 13  9 11  7  9  5

Jadi sekarang kita telah menetapkan $xuntuk menjadi array cabang (yaitu, string). Di luar loop, kita sekarang membangun "atas" pohon kami dengan jumlah ruang yang tepat disimpan $y, kemudian menampilkan cabang kami $x, dan kemudian pohon "bawah" dengan *. Masing-masing dibiarkan di jalur pipa dan hasilnya tersirat dengan baris baru di antara item.

AdmBorkBork
sumber
1

JavaScript (ES6), 150 147 byte

N=>{for(s=' '[r='repeat'](N/2-1),s+=`___
${s}\\ /
${s} |
`,n=N,l=n=>' '[r](N/2-n/2)+(n-1?`<${'-'[r](n-2)}>
`:'*');n-3;n-=2)s+=l(n)+l(n-4)
return s}

Darrylyeo
sumber
1

Kanvas , 28 byte

-×>+∔
__¶ /¶|╶┤r⇵{├⁸¹⁸}k*∔↔│

Coba di sini!

Port jawaban SOGL saya yang merupakan port jawaban Neil's Charcoal.

dzaima
sumber
0
N=>{for(s=' '[r='repeat'](N/2-1),s+=`___
${s}\\ /
${s} |
`,l=n=>' '[r](N/2-n/2)+n-1?`<${'-'[r](n-2)}>
`:'*');N-=2;s+=l(N)+l(N-4);return s}

Usaha saya di JS ESGoogoltriplex.

pengguna75200
sumber