Asterischi virali


9

Dato un intero positivo N ("viralità"), il tuo programma dovrebbe creare un disegno in stile ASCII di un albero con due rami della lunghezza N che si estendono verso il basso e / o verso destra dall'angolo in alto a sinistra.

La direzione presa da ciascun ramo dopo il primo asterisco può essere verso destra o verso il basso, e questa scelta dovrebbe essere fatta casualmente 1 ad ogni passaggio successivo.

Ad esempio, dato un input di 5, l'output potrebbe apparire come:

***
* ***
**
 **

I due rami sono autorizzati a toccare (essere su celle adiacenti), ma non si sovrappongono (si trovano sulla stessa cella), quindi non è consentito quanto segue:

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

Esempi

Per l'input 1, l'unico output possibile è:

**
*

(Questo sarà presente in tutti gli output validi, poiché avere i due rami nello stesso percorso li farebbe sovrapporre.)

Le possibili uscite per un ingresso di 3includono:

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

Per input 7:

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

Per input 10:

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

Questo è , quindi vince la risposta valida più breve (in byte).

1. Questo dovrebbe essere uniformemente casuale (cioè una probabilità 50/50 di ciascuna direzione), o quanto più uniformemente casuale possibile su un normale hardware.


Per favore, commenta se hai problemi con il consumo del mio post lungo - forse posso accorciare qualcosa (proverò poi).
nicael

3
Impara solo ad aspettartelo. A volte è occupato come diamine. Altre volte è silenzioso come adesso. Non dimenticare, è anche Pasqua.
Zacharý,

Non sono davvero sicuro di cosa non vada nel mio post. Per favore, colui che ha effettuato il downvoting sarebbe così gentile da spiegare?
nicael

1
IMO N è meglio descritto come ora: P
ASCII

1
Possiamo tornare una matrice di 0s e 1s invece di spazi ed asterischi?
dylnan,

Risposte:


5

CJam , 58 51 byte

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

Provalo online!

L'idea di base è che iniziamo con [0 0]e poi aggiungiamo ripetutamente 0 o 1 a ciascun elemento (assicurandoci che non siano mai uguali tranne all'inizio per evitare sovrapposizioni), raccogliendo tutti i risultati intermedi.

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

Creiamo quindi una vasta gamma di array in cui ogni subarray contiene *indici forniti dalla coppia corrispondente nell'array originale e spazi ovunque.

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

Ciò produce sezioni diagonali della matrice di output (dove spostarsi da sinistra a destra corrisponde a spostarsi da destra a destra in basso a sinistra nella matrice effettiva).

Possiamo quindi usare ::a:.+per "de-diagonalizzare" e ottenere le linee risultanti:

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

3

Carbone , 31 24 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Inizialmente pensavo che sarebbe stato più semplice rendere casuale il primo passo, ma si è rivelato più golfista per rendere prevedibile il primo ramo. Spiegazione:

F²«

Ripeti due volte, usando la variabile indice i. (Questo in realtà scorre su un elenco implicito, quindi è sicuro mutare iall'interno del ciclo.)

J⁰¦⁰

Vai all'origine della tela.

F⊕θ«

N+1Tempi di ciclo .

¿ι*↓*

Stampa a *, ma lascia il cursore a destra o sotto il cursore a seconda del valore di i.

‽²ι

Randomizza il valore di iper la successiva iterazione del ciclo interno.

¿KK↗

Se il personaggio attuale è a *, questo significa che siamo il secondo ramo e siamo scesi invece che a destra, quindi spostati in alto a destra per correggerlo. (Il primo ramo inizia sempre verso il basso, quindi il secondo ramo sarà sempre sopra di esso, il che significa che dobbiamo solo verificare la presenza di una collisione verticale.)


È quasi corretto, tuttavia stampa Nrami non dimensionati, ma di N-1dimensioni :)
nicael

@nicael Siamo spiacenti, risolto.
Neil,

Probabilmente l'hai già visto troppe volte, ma: 23 byte
solo ASCII il

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

Provalo online qui .

Grazie a Kevin Cruijssen per il golf 29 byte.

Versione non golfata:

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 byte (ho cambiato solo do{}un po ' le cose all'interno (e ho inserito gli inte nella prima parte del for-loop). PS: Nella tua risposta iniziale, 0.5avrebbe potuto anche giocare a golf .5.
Kevin Cruijssen

@KevinCruijssen sembra che abbia bisogno di lavorare sulla mia matematica. grazie :-)
OOBalance

3

Perl 5 , 208 124 122 118 byte

118 byte senza righe, rientri e commenti. Prende N da 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

Provalo online!


Bello, ma stampa i rami 1 asterisco più corto di quanto dovrebbero essere :)
nicael

Per favore, vedi di nuovo gli esempi nelle mie domande :)
nicael

Oh, sono passato 2..$Na 1..shiftora e mi sono anche rasato alcuni byte.
Kjetil S.

1
Buona risposta! È possibile salvare alcuni byte utilizzando <>e input anziché shifte argomenti e riordinando le informazioni chiamate randper evitare le parentesi. Non dovresti aver bisogno di concludere il tuo compito @o. Ho provato a usare @b=([],[]);quale sembra funzionare, ma non ho sperimentato troppo, quindi avrei potuto perdere un caso limite lì. Spero che aiutino un po '!
Dom Hastings,

1
I consigli per giocare a golf nella pagina Perl hanno dei buoni consigli, assicurati di dare un'occhiata! Buona fortuna e buon divertimento!
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]

Provalo online!


2

Perl 5 -a , 97 96 93 92 byte

Non ha distorsione diagonale destra, giù o fuori.

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

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

richiede PHP 5.4 o successivo per l'operatore Elvis. Sostituisci ?:con ?1:per PHP precedente.

Esegui come pipe -nRo provalo online .


1
Come posso verificare con input diversi lì?
nicael,

@nicael: puoi cambiare l'argomento sulla linea$argBak=$argn=
Galen Ivanov,

Ok! Non sono sicuro che sia un modo carino o meno di "accettare" l'input in questo modo, ma lascia che la comunità decida votando
nicael

@nicael Nel TiO, è sufficiente sostituire il valore per $argn. In un ambiente reale, $argnviene da STDIN se lo si esegue come pipe con -R. Eseguirà quindi il codice per ogni riga di input (ma sono abbastanza certo che PHP non disinserisce le variabili tra di loro; quindi le esecuzioni consecutive esplicite hanno maggiori probabilità di evitare brutte sorprese.)
Titus

0

Rosso , 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]

Provalo online!

Leggibile:

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

Gelatina , 50 43 41 byte

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

Provalo online!

È stato davvero divertente da scrivere. Potrebbe esserci un metodo molto più ottimale. Probabilmente c'è anche del golf da fare in questo metodo.

Subito dopo aver pubblicato questo mi sono reso conto che avrei potuto usare ,þ`invece di 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,,"")

Provalo online!

Inoltre, sebbene non soddisfi le specifiche di output, puoi distinguere i due rami: provalo online!

Spiegazione:

A partire dall'indice 1, selezioniamo casualmente una mossa destra o sinistra per il ramo raggiungendo no 1, rispettivamente. Quindi selezioniamo un'altra mossa destra o sinistra per la diramazione ke se si interseca dove rsta andando, selezioniamo l'altra direzione. Quindi usiamo re kcome indici in m, impostando quei valori come "*". n-1Tempi di iterazione , quindi stampiamo il risultato.


0

Gelatina , 39 38 byte

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

Provalo online!

Sebbene apparentemente non correlato, dè utile qui per salvare un byte (rispetto al mio approccio precedente).


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)

Provalo online!

Python ha il supporto nativo per numeri complessi del modulo a+bj; questo rende alcuni problemi 2D un po 'più trattabili ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.