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.


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:

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

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ą).


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
}

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!


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!


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!


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 .


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
]

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þ`Ɗ.


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.


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


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 ...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.