Asteriscos virais

9

Dado um número inteiro positivo N ("viralidade"), seu programa deve criar um desenho de uma árvore com arte ASCII com dois ramos de comprimento N estendendo-se para baixo e / ou para a direita a partir do canto superior esquerdo.

A direção adotada por cada ramo após o primeiro asterisco pode ser para a direita ou para baixo, e essa escolha deve ser feita aleatoriamente 1 a cada passo seguinte.

Por exemplo, dada uma entrada 5, a saída pode se parecer com:

***
* ***
**
 **

Os dois ramos têm permissão para tocar (estar nas células adjacentes), mas não se sobrepõem (estar na mesma célula), portanto, o seguinte não seria permitido:

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

Exemplos

Para entrada 1, a única saída possível é:

**
*

(Isso estará presente em todas as saídas válidas, pois ter as duas ramificações no mesmo caminho causaria a sobreposição.)

Possíveis saídas para uma entrada de 3incluem:

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

Para entrada 7:

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

Para entrada 10:

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

Isso é , então a resposta mais curta e válida (em bytes) vence.

1. Isso deve ser aleatório uniformemente (ou seja, 50/50 de chance para cada direção) ou o mais próximo possível de ser aleatório uniformemente possível no hardware normal.

nicael
fonte
Comente se você está tendo problemas para consumir meu longo post - talvez eu possa reduzir algo (tentarei então).
Nicael 01/04
3
Apenas aprenda a esperar isso. Às vezes, está ocupado como todos. Outras vezes, fica quieto como está agora. Não se esqueça, também é Páscoa.
Zachary
Não tenho muita certeza do que há de errado com minha postagem. Aquele que votou mal seria tão gentil em explicar, por favor?
Nicael
11
O IMO N é melhor descrito como tempo: P
somente ASCII
11
Podemos retornar uma matriz de 0s e 1s em vez de espaços e asteriscos?
dylnan

Respostas:

5

CJam , 58 51 bytes

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

Experimente online!

A idéia básica é que começamos com [0 0]e depois adicionemos 0 ou 1 repetidamente a cada elemento (certificando-se de que eles nunca sejam iguais, exceto no início, para evitar sobreposição), coletando todos os resultados intermediários.

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

Em seguida, criamos uma grande variedade de matrizes, onde cada sub-matriz contém *índices fornecidos pelo par correspondente na matriz original e espaços em qualquer outro lugar.

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

Isso gera fatias diagonais da matriz de saída (onde mover da esquerda para a direita corresponde a mover da direita para a esquerda na matriz real).

Podemos então usar ::a:.+para "des diagonalizar" e obter as linhas resultantes:

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]
Esolanging Fruit
fonte
3

Carvão , 31 24 bytes

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

Experimente online! Link é a versão detalhada do código. Originalmente, eu pensei que seria mais fácil tornar o primeiro passo aleatório, mas acabou sendo mais golfista para tornar o primeiro ramo previsível. Explicação:

F²«

Loop duas vezes, usando a variável index i. (Na verdade, ele itera sobre uma lista implícita, por isso é seguro alternar identro do loop.)

J⁰¦⁰

Ir para a origem da tela.

F⊕θ«

N+1Tempos de loop .

¿ι*↓*

Imprima a *, mas deixe o cursor para a direita ou abaixo do cursor, dependendo do valor de i.

‽²ι

Aleatoriamente o valor de ipara a próxima iteração do loop interno.

¿KK↗

Se o caractere atual é a *, isso significa que somos o segundo ramo e descemos ao invés do direito, então mova para a direita para corrigir isso. (O primeiro ramo sempre começa para baixo, portanto o segundo ramo sempre estará acima dele, o que significa que precisamos apenas verificar uma colisão vertical.)

Neil
fonte
É quase certo, no entanto, as impressões não Nramos -sized, mas N-1tamanho :)
nicael
@nicael Desculpe, corrigido.
214 Neil
Você provavelmente já viu isso muitas vezes, mas: 23 bytes
ASCII-only
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;}

Experimente online aqui .

Agradecimentos a Kevin Cruijssen por jogar 29 bytes.

Versão não destruída:

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
fonte
239 bytes (apenas mudei as coisas dentro de do{}um pouco (e coloquei as entradas na primeira parte do loop for). PS: Na sua resposta inicial, também 0.5poderia ter sido .5
jogado no golfe
@KevinCruijssen parece que eu preciso trabalhar na minha matemática. Obrigado :-)
OOBalance 03/04
3

Perl 5 , 208 124 122 118 bytes

118 bytes sem novas linhas, recuo e comentários. 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

Experimente online!

Kjetil S.
fonte
Bom, mas ele imprime os ramos 1 asterisco mais curtos do que deveriam ser :)
nicael
Por favor, veja os exemplos em minhas perguntas novamente :)
nicael
Ah, mudei 2..$Npara 1..shiftagora e também retirei alguns bytes.
precisa
11
Boa resposta! Você pode salvar alguns bytes usando <>e inserir, em vez de shiftargumentos, bem como reordená-lo randpara evitar os parênteses. Você também não precisa encerrar sua tarefa @o. Eu tentei usar o @b=([],[]);que parece funcionar, mas eu não experimentei muito, então talvez eu tenha esquecido um caso básico lá. Espero que eles ajudem um pouco!
Dom Hastings
11
As dicas para jogar golfe na página Perl têm alguns bons conselhos, não deixe de conferir! Boa sorte e divirta-se!
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]

Experimente online!

Erik, o Outgolfer
fonte
2

Perl 5 -a , 97 96 93 92 bytes

Não possui viés diagonal à direita, para baixo ou para fora.

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

Experimente online!

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

requer PHP 5.4 ou posterior para o operador Elvis. Substitua ?:com ?1:PHP mais velho.

Execute como pipe -nRou experimente online .

Titus
fonte
11
Como verifico com entradas diferentes lá?
Nicael 2/04
@nicael: Você pode mudar o argumento na linha$argBak=$argn=
Galen Ivanov
Está bem! Não tenho certeza se esta é uma boa forma ou não "aceitar" input desta maneira, mas deixar a comunidade decidir por votação
nicael
@nicael No TiO, basta substituir o valor para $argn. Em um ambiente real, $argnvem do STDIN se você o executa como um pipe -R. Ela irá então executar o código para cada linha de entrada (mas estou certo de PHP não resetar as variáveis inbetween, assim explícitas corridas consecutivas são mais propensos a evitar surpresas ruins.)
Tito
0

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

Experimente online!

Legível:

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
fonte
0

Geléia , 50 43 41 bytes

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

Experimente online!

Foi realmente divertido escrever isso. Poderia haver algum método muito mais ideal. Provavelmente, também há golfe a fazer dentro deste método.

Logo após eu postar isso, percebi que poderia usar em ,þ`vez de aþ,""oþ`Ɗ.

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

Experimente online!

Além disso, embora não atenda às especificações de saída, você pode distinguir os dois ramos: Experimente online!

Explicação:

A partir do índice 1, selecionamos aleatoriamente um movimento para a direita ou para a esquerda para ramificação radicionando nou 1, respectivamente. Em seguida, selecionamos outro movimento à direita ou à esquerda para ramificação ke, se ele se cruzar para onde restá indo, selecionamos a outra direção. Em seguida, usamos re kcomo índices em m, definindo esses valores como "*". Repetindo os n-1tempos, imprimimos o resultado.

Giuseppe
fonte
0

Geléia , 39 38 bytes

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

Experimente online!

Embora aparentemente não relacionado, dé útil aqui para salvar um byte (sobre minha abordagem anterior).

user202729
fonte
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)

Experimente online!

O Python possui suporte nativo para números complexos do formulário a+bj; isso torna alguns problemas 2D um pouco mais tratáveis ​​...

Chas Brown
fonte