Asteriscos virales

9

Dado un número entero positivo N ("viralidad"), su programa debe crear un dibujo ASCII de un árbol con dos ramas de longitud N que se extiendan hacia abajo y / o hacia la derecha desde la esquina superior izquierda.

La dirección tomada por cada rama después del primer asterisco puede ser hacia la derecha o hacia abajo, y esta elección debe hacerse al azar 1 en cada paso siguiente.

Por ejemplo, dada una entrada de 5, la salida podría verse así:

***
* ***
**
 **

Las dos ramas pueden tocar (estar en celdas adyacentes), pero no superponerse (estar en la misma celda), por lo que no se permitiría lo siguiente:

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

Ejemplos

Para la entrada 1, la única salida posible es:

**
*

(Esto estará presente en todas las salidas válidas, ya que hacer que las dos ramas tomen el mismo camino provocaría que se superpongan).

Las salidas posibles para una entrada de 3incluyen:

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

Para entrada 7:

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

Para entrada 10:

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

Este es el , por lo que gana la respuesta válida más corta (en bytes).

1. Esto debería ser aleatorio de manera uniforme (es decir, una probabilidad de 50/50 de cada dirección), o tan aleatorio como sea posible en un hardware normal.

nicael
fuente
Comenta si tienes problemas para consumir mi publicación larga, tal vez pueda acortar algo (lo intentaré luego).
nicael 01 de
3
Solo aprende a esperar eso. A veces está ocupado como diablos. Otras veces es tranquilo como lo es ahora. No lo olvides, también es Pascua.
Zacharý
No estoy realmente seguro de lo que está mal en mi publicación. ¿Sería tan amable de explicar el que votó por favor?
nicael
1
La OMI N se describe mejor como tiempo: P
Solo ASCII
1
Se puede devolver una matriz de 0s y 1s en lugar de espacios y asteriscos?
dylnan

Respuestas:

5

CJam , 58 51 bytes

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

Pruébalo en línea!

La idea básica es que comencemos [0 0]y luego agreguemos repetidamente 0 o 1 a cada elemento (asegurándonos de que nunca sean iguales excepto al principio para evitar la superposición), recopilando todos los resultados intermedios.

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

Luego creamos una gran variedad de matrices donde cada subconjunto contiene *índices dados por el par correspondiente en la matriz original y espacios en cualquier otro lugar.

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

Esto produce cortes diagonales de la matriz de salida (donde moverse de izquierda a derecha corresponde a moverse de arriba a derecha a abajo a la izquierda en la matriz real).

Luego podemos usar ::a:.+para "des-diagonalizar" y obtener las líneas resultantes:

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]
Fruta Esolanging
fuente
3

Carbón , 31 24 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Originalmente pensé que sería más fácil hacer que el primer paso fuera aleatorio, pero resultó ser más golfista hacer que la primera rama fuera predecible. Explicación:

F²«

Bucle dos veces, utilizando la variable de índice i. (Esto en realidad itera sobre una lista implícita, por lo que es seguro mutar identro del bucle).

J⁰¦⁰

Salta al origen del lienzo.

F⊕θ«

N+1Tiempos de bucle .

¿ι*↓*

Imprima a *, pero deje el cursor a la derecha o debajo del cursor según el valor de i.

‽²ι

Aleatorice el valor de ipara la próxima iteración del bucle interno.

¿KK↗

Si el personaje actual es un *, esto significa que somos la segunda rama y bajamos en lugar de la derecha, así que sube a la derecha para corregir eso. (La primera rama siempre comienza hacia abajo, por lo que la segunda rama siempre estará por encima de ella, lo que significa que solo necesitamos verificar una colisión vertical).

Neil
fuente
Es casi correcto, sin embargo, imprime Nramas no de tamaño, pero de N-1tamaño :)
nicael 02 de
@nicael Lo siento, arreglado.
Neil
Probablemente ya haya visto esto muchas veces, pero: 23 bytes
solo ASCII el
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;}

Pruébelo en línea aquí .

Gracias a Kevin Cruijssen por jugar al golf 29 bytes.

Versión sin golf:

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
fuente
239 bytes (solo he cambiado las cosas dentro de do{}un poco (y coloqué las entradas en la primera parte del ciclo for). PD: En su respuesta inicial, también se 0.5podría haber jugado golf .5.
Kevin Cruijssen
@KevinCruijssen parece que necesito trabajar en mis matemáticas. gracias :-)
OOBalance
3

Perl 5 , 208 124 122 118 bytes

118 bytes sin líneas nuevas, sangría y comentarios. Toma N de 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

Pruébalo en línea!

Kjetil S.
fuente
Niza, pero imprime las ramas 1 asterisco más cortos de lo que deberían ser :)
nicael
Por favor vea los ejemplos en mis preguntas nuevamente :)
nicael
Oh, he cambiado 2..$Na 1..shiftahora y también recorté algunos bytes.
Kjetil S.
1
¡Buena respuesta! Puede guardar algunos bytes usando <>y entrada en lugar de shiftargumentos, así como reordenar si llama randpara evitar los parens. No debería necesitar ajustar su tarea a @oninguno de los dos. Intenté usar el @b=([],[]);que parece funcionar, pero no experimenté demasiado, así que podría haber perdido un caso límite allí. Espero que ayuden un poco!
Dom Hastings
1
Los consejos para jugar al golf en la página de Perl tienen algunos buenos consejos, ¡asegúrate de echarle un vistazo! ¡Buena suerte y diviertete!
Dom Hastings
2

Python 2 , 204 bytes

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]

Pruébalo en línea!

Erik el Outgolfer
fuente
2

Perl 5 -a , 97 96 93 92 bytes

No tiene sesgo diagonal derecha, abajo o fuera.

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

Pruébalo en línea!

Ton Hospel
fuente
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);

requiere PHP 5.4 o posterior para el operador de Elvis. Reemplazar ?:con ?1:PHP anterior.

Ejecutar como tubería -nRo probarlo en línea .

Tito
fuente
1
¿Cómo verifico con diferentes entradas allí?
nicael
@nicael: Puedes cambiar el argumento en la línea$argBak=$argn=
Galen Ivanov
¡Okay! No estoy seguro de si esto es una buena manera o no a "aceptar" entrada de esta manera, pero no que la comunidad decida por votación
nicael
@nicael En el TiO, simplemente reemplace el valor de $argn. En un entorno real, $argnproviene de STDIN si lo ejecuta como una tubería -R. Luego ejecutará el código para cada línea de entrada (pero estoy bastante seguro de que PHP no desarma las variables intermedias; por lo tanto, es más probable que las ejecuciones consecutivas explícitas eviten malas sorpresas.)
Titus
0

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

Pruébalo en línea!

Legible:

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 Ivanov
fuente
0

Jalea , 50 43 41 bytes

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

Pruébalo en línea!

Fue muy divertido escribirlo. Podría haber algún método mucho más óptimo. Probablemente también hay algo de golf que hacer dentro de este método.

Justo después de publicar esto, me di cuenta de que podía usarlo en ,þ`lugar de aþ,""oþ`Ɗ.

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

Pruébalo en línea!

Además, aunque no cumple con las especificaciones de salida, puede distinguir las dos ramas: ¡ Pruébelo en línea!

Explicación:

Comenzando desde el índice 1, seleccionamos aleatoriamente un movimiento hacia la derecha o hacia la izquierda para la rama ragregando no 1, respectivamente. Luego seleccionamos otro movimiento hacia la derecha o hacia la izquierda para la rama k, y si se cruzara a donde rva, seleccionamos la otra dirección. Luego usamos ry kcomo índices en m, estableciendo esos valores como "*". Iterando n-1tiempos, imprimimos el resultado.

Giuseppe
fuente
0

Jalea , 39 38 bytes

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

Pruébalo en línea!

Aunque aparentemente no destá relacionado, es útil aquí para guardar un byte (sobre mi enfoque anterior).

usuario202729
fuente
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)

Pruébalo en línea!

Python tiene soporte nativo para números complejos del formulario a+bj; Esto hace que algunos problemas 2D sean un poco más manejables ...

Chas Brown
fuente