Sternchen viral


9

Bei einer positiven Ganzzahl N ("Viralität") sollte Ihr Programm eine ASCII-Zeichnung eines Baums mit zwei Zweigen der Länge N erstellen, die sich von der oberen linken Ecke nach unten und / oder rechts erstrecken.

Die Richtung, die jeder Zweig nach dem ersten Sternchen einnimmt, kann entweder nach rechts oder nach unten sein, und diese Auswahl sollte bei jedem nächsten Schritt zufällig 1 getroffen werden.

Bei einer Eingabe von 5 könnte die Ausgabe beispielsweise folgendermaßen aussehen:

***
* ***
**
 **

Die beiden Zweige dürfen sich berühren (sich in benachbarten Zellen befinden), dürfen sich jedoch nicht überlappen (sich in derselben Zelle befinden), sodass Folgendes nicht zulässig ist:

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

Beispiele

Für die Eingabe 1ist die einzig mögliche Ausgabe:

**
*

(Dies ist in allen gültigen Ausgaben vorhanden, da sich die beiden Zweige überlappen, wenn sie denselben Pfad nehmen.)

Mögliche Ausgaben für eine Eingabe von 3umfassen:

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

Zur Eingabe 7:

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

Zur Eingabe 10:

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

Dies ist , daher gewinnt die kürzeste gültige Antwort (in Bytes).

1. Dies sollte gleichmäßig zufällig sein (dh eine 50/50-Chance für jede Richtung) oder so gleichmäßig zufällig sein, wie es mit normaler Hardware möglich ist.


Bitte kommentieren Sie, wenn Sie Probleme haben, meinen langen Beitrag zu konsumieren - vielleicht kann ich etwas verkürzen (ich werde es dann versuchen).
Nicael

3
Lerne einfach, das zu erwarten. Manchmal ist es verdammt beschäftigt. Ein anderes Mal ist es ruhig wie jetzt. Vergiss nicht, es ist auch Ostern.
Zacharý

Ich bin mir nicht sicher, was mit meinem Beitrag los ist. Wäre derjenige, der herabgestimmt hat, bitte so freundlich zu erklären?
Nicael

1
IMO N wird besser als Zeit beschrieben: P
Nur ASCII

1
Können wir eine Matrix aus 0s und 1s anstelle von Leerzeichen und Sternchen zurückgeben?
Dylnan

Antworten:


5

CJam , 58 51 Bytes

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

Probieren Sie es online aus!

Die Grundidee ist, dass wir mit [0 0]jedem Element beginnen und dann wiederholt entweder 0 oder 1 hinzufügen (wobei sichergestellt wird, dass sie nur zu Beginn gleich sind, um Überlappungen zu vermeiden), um alle Zwischenergebnisse zu sammeln.

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

Wir erstellen dann ein großes Array von Arrays, in denen jedes Subarray *Indizes enthält , die durch das entsprechende Paar im ursprünglichen Array angegeben sind, und überall sonst Leerzeichen.

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

Dies ergibt diagonale Schichten der Ausgabematrix (wobei das Verschieben von links nach rechts dem Verschieben von oben rechts nach unten links in der tatsächlichen Matrix entspricht).

Wir können dann verwenden, ::a:.+um "zu diagonalisieren" und die resultierenden Linien zu erhalten:

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

3

Holzkohle , 31 24 Bytes

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

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Ursprünglich dachte ich, es wäre einfacher, den ersten Schritt zufällig zu machen, aber es stellte sich als Golfspiel heraus, den ersten Zweig vorhersehbar zu machen. Erläuterung:

F²«

Schleife zweimal mit Indexvariable i. (Dies iteriert tatsächlich über eine implizite Liste, sodass es sicher ist, iinnerhalb der Schleife zu mutieren .)

J⁰¦⁰

Springe zum Ursprung der Leinwand.

F⊕θ«

Schleifenzeiten N+1.

¿ι*↓*

Drucken Sie a *, aber lassen Sie den Cursor je nach Wert von entweder rechts oder unterhalb des Cursors i.

‽²ι

Randomisieren Sie den Wert von ifür die nächste Iteration der inneren Schleife.

¿KK↗

Wenn das aktuelle Zeichen a ist *, bedeutet dies, dass wir der zweite Zweig sind und statt rechts nach unten gegangen sind. Bewegen Sie sich also nach rechts, um dies zu korrigieren. (Der erste Zweig beginnt immer nach unten, sodass der zweite Zweig immer darüber liegt, was bedeutet, dass wir nur nach einer vertikalen Kollision suchen müssen.)


Es ist fast richtig, aber es druckt nicht- Ngroße Zweige, aber N-1Größe :)
Nicael

@nicael Sorry, behoben.
Neil

Sie haben dies wahrscheinlich schon zu oft gesehen, aber: 23 Bytes
ASCII-nur

3

Java 10, 273 272 268 239 Bytes

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

Probieren Sie es hier online aus .

Vielen Dank an Kevin Cruijssen für das Golfen von 29 Bytes.

Ungolfed Version:

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 (Ich habe nur die Dinge im Inneren do{}ein wenig geändert (und die Ints im ersten Teil der for-Schleife platziert). PS: In Ihrer ersten Antwort 0.5hätte man auch Golf spielen können .5.
Kevin Cruijssen

@ KevinCruijssen sieht so aus, als müsste ich an meiner Mathematik arbeiten. danke :-)
OOBalance

3

Perl 5 , 208 124 122 118 Bytes

118 Bytes ohne Zeilenumbrüche, Einrückungen und Kommentare. Nimmt N von 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

Probieren Sie es online aus!


Schön, aber es druckt die Zweige 1 Sternchen kürzer als sie sein sollten :)
Nicael

Bitte sehen Sie die Beispiele in meinen Fragen noch einmal :)
Nicael

Oh, ich habe mich 2..$Nauf 1..shiftjetzt geändert und auch ein paar Bytes rasiert.
Kjetil S.

1
Gute Antwort! Sie können ein paar Bytes mit <>und anstelle von shiftund Argumenten speichern sowie die von Ihnen aufgerufene Neuanordnung rand, um die Parens zu vermeiden. Sie sollten Ihre Aufgabe auch nicht abschließen müssen @o. Ich habe versucht, @b=([],[]);das zu verwenden, was zu funktionieren scheint, aber ich habe nicht zu viel experimentiert, sodass ich dort möglicherweise einen Randfall verpasst habe. Hoffe sie helfen ein wenig!
Dom Hastings

1
Die Tipps zum Golfen auf der Perl-Seite enthalten einige gute Ratschläge. Schauen Sie sich diese unbedingt an! Viel Glück und hab Spaß!
Dom Hastings



1

PHP, 118 Bytes

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

erfordert PHP 5.4 oder höher für den Elvis-Operator. Ersetzen Sie ?:durch ?1:für älteres PHP.

Laufen Sie als Pipe mit -nRoder probieren Sie es online aus .


1
Wie überprüfe ich dort mit unterschiedlichen Eingaben?
Nicael

@nicael: Sie können das Argument in der Zeile ändern$argBak=$argn=
Galen Ivanov

In Ordnung! Ich
bin

@nicael Ersetzen Sie im TiO einfach den Wert für $argn. In einer realen Umgebung $argnkommt von STDIN, wenn Sie es als Pipe mit ausführen -R. Es wird dann den Code für jede Eingabezeile ausführen (aber ich bin mir ziemlich sicher, dass PHP die Variablen dazwischen nicht deaktiviert; explizite aufeinanderfolgende Läufe vermeiden eher böse Überraschungen.)
Titus

0

Rot , 195 190 Bytes

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]

Probieren Sie es online aus!

Lesbar:

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

Gelee , 50 43 41 Bytes

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

Probieren Sie es online aus!

Es hat wirklich Spaß gemacht, dies zu schreiben. Es könnte eine viel optimalere Methode geben. Es gibt wahrscheinlich auch einige Möglichkeiten zum Golfen innerhalb dieser Methode.

Gleich nachdem ich dies gepostet hatte, wurde mir klar, dass ich ,þ`stattdessen verwenden könnte aþ,""oþ`Ɗ.


0

R , 148 142 Bytes

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

Probieren Sie es online aus!

Obwohl es nicht der Ausgabespezifikation entspricht, können Sie die beiden Zweige unterscheiden: Probieren Sie es online aus!

Erläuterung:

Ausgehend von Index 1wählen wir zufällig eine rechts oder links für Zweig rdurch Hinzufügen noder 1sind. Dann wählen wir eine andere Rechts- oder Linksbewegung für den Zweig aus k, und wenn sie sich überschneiden rwürde, wählen wir die andere Richtung. Dann verwenden wir rund kals Indizes in mund setzen diese Werte als "*". Durchlaufzeiten n-1drucken wir dann das Ergebnis.


0

Gelee , 39 38 Bytes

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

Probieren Sie es online aus!

Obwohl dies scheinbar nichts miteinander zu tun hat, dist es hier nützlich, ein Byte zu speichern (gegenüber meinem vorherigen Ansatz).


0

Python 2 , 191 187 176 Bytes

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)

Probieren Sie es online aus!

Python bietet native Unterstützung für komplexe Zahlen des Formulars a+bj. Dies macht einige 2-D-Probleme ein bisschen leichter zu handhaben ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.