Gwiazdki wirusowe

9

Biorąc pod uwagę dodatnią liczbę całkowitą N („virality”), twój program powinien utworzyć rysunek drzewa ASCII z dwoma gałęziami o długości N rozciągającymi się w dół i / lub w prawo od lewego górnego rogu.

Kierunek obrany przez każdą gałąź po pierwszej gwiazdce może być w prawo lub w dół, a tego wyboru należy dokonywać losowo 1 na każdym kolejnym kroku.

Na przykład przy danych wejściowych 5 wynik może wyglądać następująco:

***
* ***
**
 **

Dwie gałęzie mogą się dotykać (znajdować się na sąsiednich komórkach), ale nie mogą się nakładać (znajdować się na tej samej komórce), więc następujące elementy nie będą dozwolone:

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

Przykłady

W przypadku danych wejściowych 1jedynym możliwym wyjściem jest:

**
*

(Będzie to obecne na wszystkich prawidłowych danych wyjściowych, ponieważ dwie gałęzie idące tą samą ścieżką spowodowałyby ich nakładanie się.)

Możliwe dane wyjściowe 3obejmują:

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

Do wprowadzenia 7:

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

Do wprowadzenia 10:

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

To jest , więc wygrywa najkrótsza poprawna odpowiedź (w bajtach).

1. Powinno to być równomiernie losowe (tj. Szansa 50/50 dla każdego kierunku), lub tak zbliżone do równomiernie losowego, jak to możliwe na normalnym sprzęcie.

Nicość
źródło
Proszę o komentarz, jeśli masz jakiekolwiek problemy ze spożywaniem mojego długiego postu - może mogę coś skrócić (wtedy spróbuję).
Nicola
3
Naucz się tego oczekiwać. Czasami jest zajęty jak do cholery. Innym razem jest tak cicho jak teraz. Nie zapomnij, to także Wielkanoc.
Zacharý
Nie jestem do końca pewien, co jest nie tak z moim postem. Czy ten, kto przegłosował głos, byłby tak uprzejmy wyjaśnić, proszę?
Nicola
1
IMO N lepiej opisać jako czas: P
tylko ASCII
1
Czy możemy zwrócić macierz 0s i 1zamiast spacji i gwiazdek?
dylnan

Odpowiedzi:

5

CJam , 58 51 bajtów

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

Wypróbuj online!

Podstawową ideą jest to, że zaczynamy od, [0 0]a następnie wielokrotnie dodajemy 0 lub 1 do każdego elementu (upewniając się, że nigdy nie są równe, chyba że na początku, aby uniknąć nakładania się), zbierając wszystkie wyniki pośrednie.

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

Następnie tworzymy dużą tablicę tablic, w której każda podtablica zawiera *indeksy podane przez odpowiednią parę w oryginalnej tablicy i spacje wszędzie indziej.

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

Daje to przekątne wycinki macierzy wyjściowej (gdzie przesunięcie od lewej do prawej odpowiada przesunięciu od góry z prawej do dołu z lewej strony w rzeczywistej macierzy).

Następnie możemy użyć ::a:.+do „odkątkowania” i uzyskania wynikowych linii:

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]
Esolanging Fruit
źródło
3

Węgiel drzewny , 31 24 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Początkowo myślałem, że łatwiej będzie zrobić pierwszy krok losowo, ale okazało się, że golfistą jest, aby pierwsza gałąź była przewidywalna. Wyjaśnienie:

F²«

Zapętl dwa razy, używając zmiennej indeksu i. (W rzeczywistości iteruje się po niejawnej liście, więc można bezpiecznie mutować iwewnątrz pętli).

J⁰¦⁰

Przejdź do początku płótna.

F⊕θ«

N+1Czasy pętli

¿ι*↓*

Wydrukuj a *, ale pozostaw kursor w prawo lub poniżej kursora, w zależności od wartości i.

‽²ι

Losuj wartość idla następnej iteracji pętli wewnętrznej.

¿KK↗

Jeśli obecna postać to a *, oznacza to, że jesteśmy drugą gałęzią i zeszliśmy w dół zamiast w prawo, więc przesuń się w górę, aby to poprawić. (Pierwsza gałąź zawsze zaczyna się w dół, więc druga gałąź zawsze będzie nad nią, co oznacza, że ​​musimy tylko sprawdzić kolizję pionową).

Neil
źródło
Jest prawie poprawny, jednak drukuje niezbyt Nduże gałęzie, ale ma N-1rozmiar :)
nicael
@nicael Przepraszamy, naprawiono.
Neil,
Prawdopodobnie już widziałeś to zbyt wiele razy, ale: 23 bajty
tylko ASCII
3

Java 10, 273 272 268 239 bajtów

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;}

Wypróbuj online tutaj .

Podziękowania dla Kevina Cruijssena za grę w golfa 29 bajtów.

Wersja bez golfa:

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
}
OOBalance
źródło
239 bajtów (Zmieniłem tylko do{}trochę rzeczy w środku (i umieściłem ints w pierwszej części pętli for). PS: W twojej początkowej odpowiedzi 0.5mogłem .5również
zagrać w
@KevinCruijssen wygląda na to, że muszę popracować nad matematyką. dzięki :-)
OOBalance
3

Perl 5 , 208 124 122 118 bajtów

118 bajtów bez znaków nowej linii, wcięć i komentarzy. Bierze N ze standardowego:

@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

Wypróbuj online!

Kjetil S.
źródło
Fajnie, ale drukuje gałęzie o 1 gwiazdkę krócej niż powinny :)
nicael
Zapoznaj się ponownie z przykładami w moich pytaniach :)
Nicola
Och, zmieniłem 2..$Nsię 1..shiftteraz i ogoliłem kilka bajtów.
Kjetil S.
1
Dobra odpowiedź! Możesz zapisać kilka bajtów, używając argumentów <>i danych wejściowych zamiast shifti argumentów, a także zmienić kolejność wywołań, randaby uniknąć parens. Nie powinieneś kończyć swojego zadania na @ożadnym z nich. Próbowałem użyć, @b=([],[]);który wydaje się działać, ale nie eksperymentowałem zbyt wiele, więc mogłem przegapić przypadek na krawędzi. Mam nadzieję, że trochę pomogą!
Dom Hastings,
1
Te wskazówki dotyczące gry w golfa na stronie Perl ma jakieś dobre rady, koniecznie sprawdź! Powodzenia i miłej zabawy!
Dom Hastings,
2

Python 2 , 204 bajty

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]

Wypróbuj online!

Erik the Outgolfer
źródło
2

Perl 5 -a , 97 96 93 92 bajty

Nie ma odchylenia w prawo, w dół ani w dół.

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

Wypróbuj online!

Ton Hospel
źródło
1

PHP, 118 bajtów

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);

wymaga PHP 5.4 lub nowszego dla operatora Elvisa. Wymień ?:się ?1:dla starszego PHP.

Uruchom jako potok z -nRlub spróbuj online .

Tytus
źródło
1
Jak mogę sprawdzić przy użyciu różnych danych wejściowych?
Nicola
@nicael: Możesz zmienić argument na linii$argBak=$argn=
Galen Iwanow
Ok! Nie jestem pewien, czy jest to dobry sposób, czy też nie „zaakceptować” danych wejściowych w ten sposób, ale niech społeczność zdecyduje, głosując
nicael
@nicael W TiO, po prostu zastąp wartość dla $argn. W prawdziwym środowisku $argnpochodzi ze STDIN, jeśli uruchamiasz go jako potok z -R. Następnie wykona kod dla każdego wiersza danych wejściowych (ale jestem pewien, że PHP nie rozłącza zmiennych między nimi; więc wyraźne kolejne uruchomienia są bardziej prawdopodobne, aby uniknąć złych niespodzianek.)
Titus
0

Czerwony , 195 190 bajtów

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]

Wypróbuj online!

Czytelny:

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
]
Galen Iwanow
źródło
0

Galaretka , 50 43 41 bajtów

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

Wypróbuj online!

To było naprawdę fajne do napisania. Może być bardziej optymalna metoda. Prawdopodobnie jest również trochę golfa w tej metodzie.

Zaraz po opublikowaniu tego zdałem sobie sprawę, że mogę użyć ,þ`zamiast aþ,""oþ`Ɗ.

dylnan
źródło
0

R , 148 142 bajtów

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,,"")

Wypróbuj online!

Dodatkowo, chociaż nie spełnia specyfikacji wyjściowej, możesz rozróżnić dwie gałęzie: Wypróbuj online!

Wyjaśnienie:

Zaczynając od indeksu 1, losowo wybieramy ruch w prawo lub w lewo dla gałęzi r, dodając odpowiednio nlub 1. Następnie wybieramy kolejny ruch w prawo lub w lewo dla gałęzi k, a jeśli przecinałby się tam, gdzie ridzie, wybieramy inny kierunek. Następnie używamy ri kjako wskaźniki dom , ustawiając te wartości jako "*". Iterowanie n-1razy, a następnie wydrukujemy wynik.

Giuseppe
źródło
0

Galaretka , 39 38 bajtów

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

Wypróbuj online!

Chociaż pozornie niezwiązane, djest przydatne tutaj, aby zapisać bajt (w porównaniu z moim poprzednim podejściem).

użytkownik202729
źródło
0

Python 2 , 191 187 176 bajtów

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)

Wypróbuj online!

Python ma natywne wsparcie dla liczb zespolonych formularza a+bj; to sprawia, że ​​niektóre problemy 2D są nieco łatwiejsze do rozwiązania ...

Chas Brown
źródło