Tanda bintang virus


9

Dengan bilangan bulat positif N ("viralitas"), program Anda harus membuat gambar seni ASCII dari pohon dengan dua cabang panjang N memanjang ke bawah dan / atau ke kanan dari sudut kiri atas.

Arah yang diambil oleh masing-masing cabang setelah tanda bintang pertama dapat berupa ke kanan atau ke bawah, dan pilihan ini harus dibuat secara acak 1 pada setiap langkah berikutnya.

Misalnya, diberi input 5, output mungkin terlihat seperti:

***
* ***
**
 **

Dua cabang diizinkan untuk menyentuh (berada di sel yang berdekatan), tetapi tidak tumpang tindih (berada di sel yang sama), sehingga hal berikut tidak akan diizinkan:

***
* *
*****
  *
  *

Contohnya

Untuk input 1, satu-satunya output yang mungkin adalah:

**
*

(Ini akan hadir di semua output yang valid, karena memiliki dua cabang mengambil jalur yang sama akan menyebabkan mereka tumpang tindih.)

Output yang mungkin untuk input 3meliputi:

***
* *
**
**
***
*
*

Untuk input 7:

****
*  **
*   **
*
***
  *

Untuk input 10:

****
*  *      
*********
  *
  *****

Ini adalah , sehingga jawaban terpendek yang valid (dalam byte) menang.

1. Ini harus acak seragam (yaitu peluang 50/50 dari setiap arah), atau sedekat mungkin dengan acak seragam yang bisa Anda dapatkan pada perangkat keras normal.


Berikan komentar jika Anda mengalami masalah dalam mengonsumsi pos lama - mungkin saya dapat mempersingkat sesuatu (saya akan coba).
nicael

3
Belajarlah untuk mengharapkan itu. Terkadang sibuk seperti semua sih. Lain kali sunyi seperti sekarang. Jangan lupa, ini juga Paskah.
Zacharý

Saya tidak begitu yakin apa yang salah dengan posting saya. Apakah orang yang turun jabatan akan berbaik hati menjelaskannya?
nicael

1
IMO N lebih baik digambarkan sebagai waktu: P
ASCII-hanya

1
Bisakah kita mengembalikan matriks 0s dan 1s bukannya spasi dan tanda bintang?
dylnan

Jawaban:


5

CJam , 58 51 byte

[TT]{_2_m*\f.+{:-},mR}ri*]ee{~\)S*\{'*t}/}%::a:.+N*

Cobalah online!

Ide dasarnya adalah bahwa kita mulai dengan [0 0]dan kemudian berulang kali menambahkan 0 atau 1 untuk setiap elemen (memastikan bahwa mereka tidak pernah sama kecuali pada awal untuk menghindari tumpang tindih), mengumpulkan semua hasil antara.

[[0 0] [0 1] [0 2] [0 2] [1 3]]

Kami kemudian membuat array array besar di mana setiap subarray berisi *indeks yang diberikan oleh pasangan yang sesuai dalam array asli dan spasi di tempat lain.

["*"
 "**"
 "* *"
 "* * "
 " * * "]

Ini menghasilkan irisan diagonal dari matriks output (di mana bergerak kiri ke kanan sesuai dengan bergerak kanan atas ke kiri bawah dalam matriks aktual).

Kita kemudian dapat menggunakan ::a:.+untuk "mendeagonisasi" dan mendapatkan baris yang dihasilkan:

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]

3

Arang , 31 24 byte

F²«J⁰¦⁰F⊕θ«¿ι*↓*≔‽²ι¿KK↗

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Awalnya saya pikir akan lebih mudah untuk membuat langkah pertama secara acak tetapi ternyata menjadi golfier untuk membuat cabang pertama dapat diprediksi. Penjelasan:

F²«

Ulangi dua kali, menggunakan variabel indeks i. (Ini sebenarnya berulang di atas daftar implisit, jadi aman untuk bermutasi idi dalam loop.)

J⁰¦⁰

Langsung ke asal kanvas.

F⊕θ«

N+1Waktu loop .

¿ι*↓*

Cetak a *, tetapi biarkan kursor berada di kanan atau di bawah kursor tergantung pada nilai i.

‽²ι

Acak nilai iuntuk iterasi loop berikutnya.

¿KK↗

Jika karakter saat ini adalah *, ini berarti bahwa kami adalah cabang kedua dan kami turun bukannya kanan, jadi naik ke kanan untuk memperbaikinya. (Cabang pertama selalu dimulai ke bawah sehingga cabang kedua akan selalu di atasnya, artinya kita hanya perlu memeriksa tabrakan vertikal.)


Ini hampir benar, namun mencetak Ncabang tidak berukuran, tetapi N-1berukuran :)
nicael

@nicael Maaf, sudah diperbaiki.
Neil

Anda mungkin sudah melihat ini terlalu sering, tetapi: 23 byte
hanya ASCII

3

Java 10, 273 272 268 239 byte

n->{var c=new char[++n][n];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,k=0,l=0,r=0,s=0,t=0,u=0;n-->0;){c[i+=r][j+=s]=c[k+=t][l+=u]=42;do{r=t=2;r*=Math.random();t*=Math.random();s=r^1;u=t^1;}while(i+r==k+t&j+s==l+u);}return c;}

Cobalah online di sini .

Terima kasih kepada Kevin Cruijssen untuk bermain golf 29 byte.

Versi tidak disatukan:

n -> { // lambda taking an int as argument
    var c = new char[++n][n]; // the output; increment the virality since the root does not count
    for(var d : c) // for every line
        java.util.Arrays.fill(d,' '); // initialize it with spaces
    for(int i = 0, j = 0, // coordinates of the first branch
            k = 0, l = 0, // coordinates of the second branch
            r = 0, s = 0, // offsets for the first branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
            t = 0, u = 0; // offsets for the second branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
        n-- > 0; ) { // decrement virality and repeat as many times
        c[i+=r][j+=s] = c[k+=t][l+=u] = 42; // move according to offsets and place an '*' for each branch, 42 is ASCII code
        do { // randomly pick offsets for both branches
            r = t = 2; // Math.random() provides results in [0,1)
            r *= Math.random(); // flip a coin for the first branch
            t *= Math.random(); // flip another coin for the second
            s = r^1; // set s to 0 if r=1, to 1 if r=0
            u = t^1; // set u to 0 if t=1, to 1 if t=0
        } while(i+r==k+t&j+s==l+u); // repeat if the branches overlap
    }
    return c; // return the output
}

239 bytes (Saya hanya mengubah hal-hal di dalam do{}bit (dan menempatkan ints di bagian pertama for-loop). PS: Dalam jawaban awal Anda 0.5bisa .5juga di
golf-kan

@KevinCruijssen sepertinya saya perlu mengerjakan matematika saya. terima kasih :-)
OOBalance

3

Perl 5 , 208 124 122 118 byte

118 byte tanpa baris baru, lekukan dan komentar. Mengambil N dari stdin:

@b=1..2;                            #number of branches is 2
for(1..<>){                         #add length <> (the input) to each branch
  ($x,$y)=@$_                       #get where current branch has its tip now
 ,.5>rand?$x++:$y++                 #increase either x or y
 ,$o[$y][$x]++&&redo                #try again if that place is already occupied
 ,$_=[$x,$y]                        #register new tip of current branch
   for@b                            #...and do all that for each branch 
}
say map$_||!$i++?'*':$",@$_ for@o;  #output the branches

Cobalah online!


Bagus, tetapi mencetak asterisk cabang 1 lebih pendek dari yang seharusnya :)
nicael

Silakan lihat contoh dalam pertanyaan saya lagi :)
nicael

Oh, saya sudah berubah 2..$Nmenjadi 1..shiftsekarang dan juga mencukur beberapa byte.
Kjetil S.

1
Jawaban yang bagus! Anda dapat menyimpan beberapa byte menggunakan <>dan memasukkan bukan shiftdan argumen serta memesan ulang Anda menelepon randuntuk menghindari parens. Anda seharusnya tidak perlu membungkus tugas Anda @ojuga. Saya mencoba menggunakan @b=([],[]);yang tampaknya berfungsi, tetapi saya tidak bereksperimen terlalu banyak sehingga saya mungkin telah melewatkan kasus tepi di sana. Semoga mereka bisa membantu sedikit!
Dom Hastings

1
The tips untuk bermain golf di halaman Perl memiliki beberapa nasihat yang baik, pastikan untuk check it out! Semoga berhasil dan selamat bersenang - senang!
Dom Hastings

2

Python 2 , 204 byte

from random import*
N=input()
s=eval(`[[' ']*-~N]*-~N`)
s[0][0]='*'
I=x,y=1,0
J=X,Y=0,1
exec"s[y][x]=s[Y][X]='*';i,j,k,l=choice((J+I,I+I,I+J,J+J)[x-2<X:]);x+=i;y+=j;X+=k;Y+=l;"*N
for i in s:print`i`[2::5]

Cobalah online!


2

Perl 5 -a , 97 96 93 92 byte

Tidak memiliki bias diagonal kanan atau bawah.

#!/usr/bin/perl -a
@;=[1];map{$x=$y=0;map++(.5<rand?$x:$y)*$;[$y][$x]++&&redo,1.."@F"}1,2;say+($","*")[@$_]for@

Cobalah online!


1

PHP, 118 byte

for($r="*",$w=$argn+2;$argn--;$r[$q+=rand(0,$r[$q+1]<"*")?:$w]=$r)$r[$p+=rand(!$i++,1)?:$w]=$r;echo wordwrap($r,$w-1);

membutuhkan PHP 5.4 atau yang lebih baru untuk operator Elvis. Ganti ?:dengan?1: untuk PHP yang lebih lama.

Jalankan sebagai pipa dengan -nRatau coba online .


1
Bagaimana saya memeriksa dengan input yang berbeda di sana?
nicael

@nicael: Anda dapat mengubah argumen di telepon$argBak=$argn=
Galen Ivanov

Baik! Tidak yakin apakah ini cara yang baik atau tidak untuk "menerima" masukan dengan cara ini, tetapi biarkan komunitas memutuskan dengan memilih
nicael

@nicael Di TiO, cukup ganti nilai untuk $argn. Dalam lingkungan nyata, $argnberasal dari STDIN jika Anda menjalankannya dengan pipa -R. Ini kemudian akan mengeksekusi kode untuk setiap baris input (tapi saya cukup yakin PHP tidak menghapus variabel di antara; jadi berturut-turut eksplisit berjalan lebih mungkin untuk menghindari kejutan buruk.)
Titus

0

Merah , 195.190 byte

func[n][g: func[s][i: 0 d: s while[i < n][b/(d): #"*"until[r: 1 if 1 = random 2[r: n + 1]b/(d + r) =#" "]d: d + r
i: i + 1]]b:""loop n[loop n[append b" "]append b"^/"]b/1: #"*"g n + 2 g 2 b]

Cobalah online!

Dapat dibaca:

f: func[n][
    g: func[s][
        i: 0
        d: s
        while[i < n][
            b/(d): #"*"
            until[
                r: 1 if 1 = random 2[r: n + 1]
                b/(d + r) = #" "
            ]
            d: d + r
            i: i + 1
        ]
    ]
    b: ""
    loop n[loop n[append b " "]append b "^/"]
    b/1: #"*"
    g n + 2
    g 2
    b
]

0

Jelly , 50 43 41 byte

2ḶẊ⁸С+\‘Ṗ
⁸ÇU;Ǥ⁻Q$¿
‘,þ`⁼€þÇS+»þ`Ị$ị⁾* 

Cobalah online!

Ini sangat menyenangkan untuk ditulis. Mungkin ada beberapa metode yang jauh lebih optimal. Mungkin ada beberapa golf yang bisa dilakukan dalam metode ini juga.

Tepat setelah saya diposting ini saya menyadari bahwa saya bisa menggunakan ,þ`bukan aþ,""oþ`Ɗ.


0

R , 148 142 byte

n=scan();`~`=sample;o=r=k=1;l=c(1,n);for(i in 1:n){r=r+l~1;t=l~1;k=k+"if"(k+t-r,t,l[l!=t]);o=c(o,r,k)};write(c(" ","*")[1:n^2%in%o+1],1,n,,"")

Cobalah online!

Selain itu, meskipun tidak memenuhi spesifikasi output, Anda dapat membedakan dua cabang: Coba online!

Penjelasan:

Mulai dari indeks 1, kami secara acak memilih gerakan kanan atau kiri untuk cabang rdengan menambahkan natau 1, masing-masing. Kemudian kita pilih gerakan kanan atau kiri untuk cabang k, dan jika akan memotong arah r, kita pilih arah yang lain. Kemudian kami menggunakan rdan ksebagai indeks ke dalam m, mengatur nilai-nilai tersebut sebagai "*". Berulang n-1kali, kami kemudian mencetak hasilnya.


0

Jelly , 39 38 byte

ḣ2+\€Ẏ
2Rd¤ṗẊÇ⁻Q$$¿Ç0,0ṭ‘Ṭ€×þ/$€Sị⁾* Y

Cobalah online!

Meskipun tampaknya tidak berhubungan, dberguna di sini untuk menyimpan byte (lebih dari pendekatan saya sebelumnya).


0

Python 2 , 191 187 176 byte

from random import*
n=input()
p,q=c=1,1j;s={p,q,0}
exec'z=choice(c);q,p=p+[z,1+1j-z][p+z in s],q;s|={q};'*2*~-n
R=range(n+1)
for y in R:print''.join(' *'[y+x*1jin s]for x in R)

Cobalah online!

Python memiliki dukungan asli untuk bilangan kompleks formulir a+bj; ini membuat beberapa masalah 2-D sedikit lebih mudah dikerjakan ...

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.