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.


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:

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

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


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

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!


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!


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!


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 .


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
]

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


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.


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


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.