Ini hampir Natal!

14

Karena itu, keluarga dari seluruh dunia membangun pohon Natal.

Tapi pohon normal ini bisa membosankan setelah beberapa saat, jadi mari kita buat pohon ASCII!

Daun diwakili oleh #dan harus diatur seperti yang ditunjukkan dalam contoh output. Kami memiliki 5 bola ( O) dan 5 tongkat permen (J ), yang kami tempatkan secara acak di sekitar pohon. Kami juga memiliki lilin di atasnya.

Masukan: tidak ada

Keluaran:

         ^
         |
        ###
       ##O##
      #######
       #####
      ####J##
     #########
    ####O######
   #############
      ###J###
     #########
    ####O###J##
   #######O#####
  ###J########O##
 ###########J#####
        ###
        ###

Aturan (jika tidak ada aturan, anggap Anda bisa)

  • Bola dan tongkat permen harus ditempatkan secara acak di pohon dan harus memiliki setidaknya satu daun di antara mereka, tidak termasuk diagonal.

  • Setiap daun harus memiliki peluang yang tidak nol untuk mendapatkan bola atau tongkat permen.

  • Mungkin ada ruang depan atau belakang di setiap garis, selama pohon itu memiliki bentuk yang tepat.

  • Ini adalah , jadi kode terpendek dalam karakter menang.

Abu-abu
sumber
2
@Billywob itu yang dekat, yang ini memiliki faktor acak dan lilin tho: P
Gray
1
Ya, ini pastinya lebih sulit.
Billywob
3
"Tapi pohon normal ini bisa membosankan setelah beberapa saat." Lalu mengapa sekolah tua lilin dan bukan sesuatu yang kreatif ?
manatwork
1
Karena tidak ada orang lain yang menyebutkan, saya akan merekomendasikan agar Anda mengirim tantangan di masa depan ke Sandbox di mana Anda bisa mendapatkan umpan balik yang berarti dan mengubah tantangan sebelum mengirimnya ke Main.
AdmBorkBork
1
Jika Anda tidak menjawab yang terlihat seperti ini , saya sarankan mencetak dengan byte daripada karakter.
Dennis

Jawaban:

4

JavaScript (ES6), 148 byte

Semoga ini sesuai dengan kondisi 'cukup acak'.

_=>[...'887656543254321077'].map(n=>' '.repeat(n)+'#'.repeat(17-2*n)).join`
`.replace(/#/g,_=>'OJ^|#'[++i<4?i:i>133|++j%13?4:j/13&1],i=1,j=new Date)

Demo

Arnauld
sumber
Saya telah menguji dan mendapatkan pohon yang menginjak 'dan harus memiliki setidaknya satu daun (#) di antara mereka, tidak termasuk diagonal'
user2216
@ user2216 Kecuali saya entah bagaimana melewatkan atau salah mengerti sesuatu, modulo dipilih sedemikian rupa sehingga tidak mungkin terjadi - kecuali sepanjang diagonal. (Ada 13 pola yang berbeda yang Anda dapat menguji dengan mengganti j=new Datedengan j=0ke j=12.)
Arnauld
8

CS-Script - 306 byte

var c=new string(' ',342).ToCharArray();var r=new Random();int e=18,i,j,w;for(;i<e;i++){c[i*e+e]='\n';w=i<5?i:i<10?i-2:i<16?i-6:2;for(j=1;j++<w*2;)c[i*e+8-w+j]='#';}for(i=0;i<10;){j=37+r.Next(288);if(c[j]=='#'&c[j+1]<42&c[j-1]<42&c[j+e]<42&c[j-e]<42)c[j]=i++<5?'J':'O';}c[8]='^';c[27]='|';Console.Write(c);

Sekali lagi dengan pemformatan dan komentar:

// create 'char bitmap' filled with spaces
var c=new string(' ',342).ToCharArray(); 
// Random for placing ornaments
var r=new Random();
int e=18,i,j,w;
// once for each row
for(;i<e;i++)
{
    // add new lines
    c[i*e+e]='\n';
    // determine width of tree for this row
    w=i<5?i:i<10?i-2:i<16?i-6:2;
    for(j=1;j++<w*2;)
        // add leaves
        c[i*e+8-w+j]='#';
}
for(i=0;i<10;)
{
    // select random location
    j=37+r.Next(288); 
    if( // check we have a leaf
        c[j]=='#' &
        // check surrounding to be leaf/space/new-line
        c[j+1]<42 & c[j-1]<42 & c[j+e]<42 & c[j-e]<42)
        // add ornament if location is valid
        c[j]=i++<5?'J':'O';
}
// light candle
c[8]='^';
c[27]='|';
// print
Console.Write(c);

Ini pada dasarnya C #, tetapi menggunakan CS-Script memungkinkan saya untuk melewati semua boiler-plate.

Coba di sini!

Catatan:

Ini saat ini menampilkan garis spasi putih di bawah pohon untuk memastikan bahwa 'memeriksa ornamen yang ada di bawah' tidak melempar IndexOutOfBoundsException. Solusi lain adalah:

  • Memeriksa apakah itu adalah baris terakhir sebelum memeriksa di bawah ini (menambahkan beberapa karakter lagi)
  • Tidak menambahkan ornamen ke 'batang' pohon (jumlah byte yang sama, tetapi menurut saya bertentangan dengan aturan)

Saya akan menyerahkannya ke OP jika ini harus diubah.

Terakhir, ini adalah golf pertama saya, jadi setiap umpan balik sangat dihargai. ;)

jimat
sumber
Solusi bagus Itu berpikir Anda mungkin perlu memasukkan using System;dalam hitungan byte Anda, karena Anda tidak dapat menggunakan Randomatau Consoletanpanya. meta.codegolf.stackexchange.com/questions/10081/... Maaf untuk menambahkan 13 byte :(
Erresen
@Erresen: Terima kasih atas tautannya! Sejauh yang saya tahu, itu hanya berbicara tentang impor yang diperlukan untuk eksekusi, dan untuk cs-script using System;tidak diperlukan (secara otomatis mengimpor ruang nama umum). Tapi mungkin aku membelah rambut. ¯_ (ツ) _ / ¯
amulware
siapa tahu! Saya sendiri baru mulai bermain kemarin. Tidak tahu tentang skrip cs sebelum melihat jawaban Anda. Sangat berguna untuk menghindari beberapa kerugian C # dalam bermain golf. Apa pun jawabannya, saya pikir skrip ac # tidak akan menang dalam waktu dekat.
Erresen
Itu sudah pasti, ya. : D
amulware
Jika Anda mengkompilasi ke suatu fungsi, jika mungkin dalam CS-Script, Anda dapat mengurangi jumlah byte yaitu_=>{var c=... return c;}
TheLethalCoder
4

TSQL, 556 532 494 476 byte

Script ini perlu dieksekusi pada database master

Golf:

DECLARE @ varchar(max)='',@h INT=0,@w INT=0WHILE @h<18SELECT
@+=space(9-@w)+REPLICATE(char(IIF(@h<2,94+30*@h,35)),@w*2+1)+space(9-@w)+CHAR(10),@h+=1,@w+=CHOOSE(@h,0,1,1,1,-1,1,1,1,1,-2,1,1,1,1,1,-8,0)WHILE
@h>7WITH C as(SELECT*,substring(@,number,1)v,number/20r,number%20c
FROM spt_values WHERE type='P'and number<358)SELECT @=stuff(@,number,1,CHAR(74+@h%2*5)),@h-=1FROM
c d WHERE v='#'and not exists(SELECT*FROM c WHERE abs(d.c-c)+abs(d.r-r)<2and'A'<v)ORDER BY newid()PRINT @

Tidak Disatukan:

DECLARE @ varchar(max)='',@h INT=0,@w INT=0

WHILE @h<18
  SELECT @+=
    space(9-@w)+REPLICATE(char(IIF(@h<2,94+30*@h,35)),@w*2+1)
      +space(9-@w)+CHAR(10),
    @h+=1,
    @w+=CHOOSE(@h,0,1,1,1,-1,1,1,1,1,-2,1,1,1,1,1,-8,0)

WHILE @h>7
  WITH C as
  (
    SELECT*,substring(@,number,1)v,number/20r,number%20c
    FROM spt_values
    WHERE type='P'and number<358
  )
  SELECT @=stuff(@,number,1,CHAR(74+@h%2*5)),@h-=1
  FROM c d
  WHERE v='#'and not exists(SELECT*FROM c WHERE abs(d.c-c)+abs(d.r-r)<2and'A'<v)
  ORDER BY newid()

PRINT @

Cobalah

t-clausen.dk
sumber
1

Python 3 - 450 427 byte

Saya tahu 450terlalu banyak untuk python. Tapi tapi.....

from random import randint as r
t=lambda o,g:(o*g).center(19,' ')+';';s,z='','#';s+=t(z,3)*2
for h,w in zip([6,5,3],[17,13,7]):
 for i in range(h):s+=t(z,w);w-=2
s+=t('|',1)+t('^',1);s=[list(i)for i in s.split(';')]
for o in'O'*5+'J'*5:
 while 1:
  h,w=r(2,15),r(1,16)
  m=s[h]
  C,m[w]=m[w],o
  P=s[h-1][w]+s[h+1][w]+m[w-1]+m[w+1]
  if not('O'in P or'J'in P)and C!=' ':break
  m[w]=C
print (*[''.join(i)+'\n'for i in s][::-1])

Jika for i in'O'*...diubah menjadi fungsi rekursif yang lebih baik maka banyak byte dapat dikurangi.

Coba di sini

Edit :

Disimpan 2 byte dengan menggunakan ;sebagai pembatas dan beberapa byte dengan mengambil jumlah byte baris baru sebagai 1 byte.

Gurupad Mamadapur
sumber
1

JavaScript, 204 byte

f=(s='^|1232345634567811'.replace(/./g,x=>(y=x|0,' '.repeat(8-y)+(y?'#'.repeat(y*2+1):x)+`
`)),o=5,j=5,r=(Math.random()*56|0)*4,k)=>j?f(s.replace(/###/g,(_,i)=>i-r?_:k=o?'#O#':'#J#'),k?o-!!o:o,k?j-!o:j):s

console.log(f());
.as-console-wrapper{max-height:100%!important;top:0}

Washington Guedes
sumber
1
mengapa Anda menghitung \nsebagai 1 byte?
Daniel Shillcock
Tidak lagi, maaf
Guedes Washington
1

PHP, 200 byte

mungkin lebih pendek dengan pendekatan yang lebih canggih; tapi saya sedang terburu-buru.

for(;$c="^|2343456745678922"[$i++];)$s.=str_pad(+$c?str_pad("",2*$c-1,"#"):$c,17," ",2)."
";for(;$n++<10;)$s[$p=rand(0,288)]!="#"|($s[$p-18]|$s[$p+18]|$s[$p-1]|$s[$p+1])>A?$n--:$s[$p]=OJ[$n&1];echo$s;

membutuhkan PHP 5.6 atau 7.0. Jalankan dengan -nratau coba online .

Titus
sumber
0

Scala, 329 byte

var r=scala.util.Random;var z=r.nextInt(2);def t{print(new StringBuilder({"^|234345645678922".map(x=>{val t=if(x>57)8 else(57-x);" "*t+{if(x>57)""+x else "#"}*(17-(t*2))+" "*t+" \n"})}.mkString)match{case e=>{var w=0;while(w<10){{val b=(r.nextInt(e.size/2)*2)+z;if(e.charAt(b)=='#'){e.setCharAt(b,if(w<5)'O'else'J');w+=1}}};e}})}
Minimal
sumber