O ponto de mudança


16

Seu programa precisa imprimir vários espaços, seguidos por um ponto e uma nova linha. O número de espaços é a posição x do seu ponto definido com 0 <x <30

Cada nova linha é uma vez. Seu programa é executado por 30 turnos. Seu programa começa com uma posição x aleatória e a cada turno muda essa posição aleatoriamente em 1 para a esquerda ou direita, enquanto permanece dentro da área definida. A cada volta, seu ponto deve mudar sua posição em 1.

Sua pontuação é o número de caracteres. Você ganha 10 pontos de bônus, se cada linha impressa tiver exatamente 30 caracteres (e nova linha). Você ganha 50 pontos de bônus, se aleatoriamente, seu programa tende a permanecer no meio da área definida.

Editar: Os 50 pontos de bônus destinam-se a puxar o seu ponto para o meio. Por exemplo, isso se aplica se o seu ponto estiver em x = 20 e tiver uma chance de 66% para a esquerda e 33% para a direita. Isso deve ser independente do ponto de partida e só deve ocorrer alterando o valor percentual de esquerda / direita dinamicamente.

Nenhuma entrada de qualquer tipo é permitida; a saída deve estar no console de execução!

Para uma melhor compreensão, aqui está um exemplo legível em java, que lhe daria uma pontuação de 723:

public class DotJumper{
    public static void main(String[] args){
        int i = (int)(Math.random()*30);
        int max = 29;
        int step = 1;
        int count = 30;
        while(count>0){
            if(i<=1){
                i+=step;
            }else if(i>=max){
                i-=step;
            }else{
                if(Math.random() > 0.5){
                    i+=step;
                }else{
                    i-=step;
                }
            }
            print(i);
            count--;
        }
    }
    public static void print(int i){
        while(i>0){
            System.out.print(' ');
            i--;
        }
        System.out.println('.');
    }
}

No seu exemplo, acho que int i = (int)(Math.random()*30);deveria ser o int i = 1 + (int)(Math.random()*29);contrário. Como é, gera um número em 0 >= x > 30vez de 0 > x > 30.
Victor Stafusa

Eu acho que o código original está correto.
user2846289

está correto, porque eu desloco primeiro e a impressão. portanto, mesmo que o valor aleatório exceda a borda, se primeiro for corrigido e depois impresso.
Reggaemuffin

@ Kostronor Mas isso implica que a posição do ponto inicial não segue uma distribuição uniforme; a primeira posição é duas vezes mais provável que as outras posições. OTOH, ser distribuído uniformemente também não era um requisito.
Victor Stafusa

Parece que seria mais difícil criar um programa em que o ponto salte mais. Então, por que há um bônus por restringir seu movimento?
Chris Laplante

Respostas:


18

APL, 39 - 10 - 50 = –21

0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29

Testado em Dyalog com ⎕IO←1e ⎕ML←3mas deve ser bastante portátil.

Explicação

                   ?29  take a random natural from 1 to 29
                31/     repeat it 31 times
              }/        reduce (right-fold) the list using the given function:
          ⍵↑''          . make a string of ⍵ (the function argument) spaces
     '.',⍨              . append a dot to its right
⎕←30↑                   . right-pad it with spaces up to length 30 and output
                ◇       . then
             ?28        . take a random natural from 1 to 28
          .5+           . add 0.5, giving a number ∊ (1.5 2.5 ... 27.5 28.5)
        ⍵>              . check whether the result is <⍵ (see explanation below)
     ¯1*                . raise -1 to the boolean result (0 1 become resp. 1 -1)
   ⍵+                   . add it to ⍵ and return it as the new accumulator value
0/{                     finally ignore the numeric result of the reduction

A cada passo, esse código decide se o ponto deve ser movido para a esquerda ou para a direita, dependendo da probabilidade de um número aleatório escolhido entre (1,5 2,5 ... 27,5 28,5) ser menor que a posição atual do ponto.

Portanto, quando a posição atual do ponto (número de espaços à esquerda) é 1, o incremento é sempre +1 (todos esses números 1,5 ... 28,5 são> 1), quando é 29, é sempre -1 (todos esses números são <29); caso contrário, é escolhido aleatoriamente entre +1 e -1, com uma probabilidade de interpolação linear entre esses extremos. Portanto, o ponto está sempre se movendo e sempre mais propenso a se mover para o centro do que para os lados. Se estiver exatamente no meio, ele tem 50% de chance de se mover para qualquer um dos lados.

A redução (dobra à direita) de um valor replicado {...}/a/bé apenas um truque que eu inventei para repetir os a-1tempos de uma função , começando com value be tendo como resultado o resultado de cada iteração o argumento acumulator ( ) para o próximo. O segundo e o próximo argumento de entrada ( ), bem como o resultado final, são ignorados. Acontece que é muito mais curto do que uma chamada recursiva regular com guarda.

Exemplo de execução

0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29
                   .          
                    .         
                   .          
                  .           
                 .            
                .             
               .              
                .             
               .              
                .             
               .              
              .               
             .                
              .               
             .                
              .               
               .              
              .               
               .              
                .             
                 .            
                  .           
                 .            
                  .           
                 .            
                  .           
                 .            
                .             
               .              
                .             

apl é uma ótima linguagem para o golfe (difícil de ler para mim); ACIMA!
blabla999

@ blabla999 O APL possui muitos símbolos comuns e alguns estranhos, mas depois que você aprende a função deles, o idioma é fácil de ler e escrever. Certamente mais fácil que o ruído ASCII dos idiomas 'golfing', mas atrevo-me a dizer que é ainda mais fácil do que os idiomas comuns. A sintaxe é muito regular, você tem apenas uma regra: as expressões são executadas da direita para a esquerda, para que possam ser lidas da esquerda para a direita: +/2×⍳9é lida "a soma de: duas vezes: as naturais até 9", mas é executado da maneira oposta.
Tobia

Sou eu ou existem 31 caracteres por linha aqui?
Gusdor 18/02

Recebo 30, copiando e colando uma linha do exemplo executado acima em um editor e verificando o código novamente. ⎕←30↑...irá imprimir 30 caracteres além de uma nova linha, não importa qual seqüência está em...
Tobia

12

Mathematica 138 - 10 - 50 = 78

Não estou publicando isso porque acho que é particularmente bom, mas por outros motivos. Ele usa uma definição de Processo de Markov com uma matriz de transição projetada para deixar a bola "centralizada".

O uso de um processo de Markov no Mathematica nos permite calcular algumas estatísticas úteis , como você verá abaixo.

Primeiro o código (espaços não necessários):

r = Range@28/28;
s = DiagonalMatrix;
ListPlot[RandomFunction[DiscreteMarkovProcess[RandomInteger@#, r~ s ~ -1 + s[29/28- r, 1]], 
                                              #], PlotRange -> #] &@{1, 29}

Algumas saídas:

Gráficos do Mathematica

A matriz de transição que usei é:

MatrixPlot[s[r, -1] + s[29/28 - r, 1]]

Gráficos do Mathematica

Mas como eu disse, a parte interessante é que o uso DiscreteMarkovProcess[]permite capturar uma boa imagem do que está acontecendo.

Vamos ver a probabilidade da bola estar 15a qualquer momento a t partir de um estado aleatório específico :

d = DiscreteMarkovProcess[RandomInteger@29, s[r, -1] + s[29/28 - r, 1]];
k[t_] := Probability[x[t] == 15, x \[Distributed] d]
ListLinePlot[Table[k[t], {t, 0, 50}], PlotRange -> All]

Gráficos do Mathematica

Você pode ver que ele varia entre 0 e um valor próximo de 0,3, porque, dependendo do estado inicial, você pode alcançar apenas 15 em um número ímpar ou par de etapas :)

Agora podemos fazer a mesma coisa, mas dizendo ao Mathematica para considerar a estatística a partir de todos os possíveis estados iniciais. Qual é a probabilidade de ficar 15depois de um tempo t?

d = DiscreteMarkovProcess[Array[1 &, 29]/29, s[r, -1] + s[29/28 - r, 1]];
k[t_] := Probability[x[t] == 15, x \[Distributed] d]
ListLinePlot[Table[k[t], {t, 0, 100}], PlotRange -> All]

Gráficos do Mathematica

Você pode ver que também oscila ... por quê? A resposta é simples: no intervalo, [1, 29]existem mais números ímpares do que pares :)

A oscilação quase desapareceu se pedirmos a probabilidade da bola estar em 14 OR 15:

Gráficos do Mathematica

E você também pode pedir o limite (no sentido Cesaro) das probabilidades de estado:

ListLinePlot@First@MarkovProcessProperties[d, "LimitTransitionMatrix"]

Gráficos do Mathematica

Bem, talvez eu mereça alguns votos negativos por uma resposta tão fora de tópico. Fique à vontade.


2
Este não é o mais curto, mas é muito legal.
Kasra Rahjerdi

Upvoted, e agora a sua pontuação não 2222 é ...
cormullion

@cormullion Thanks! Você pode desfazer que por downvoting duro :)
Dr. belisarius

7

Bash, pontuação 21 (81 bytes - bônus 50 - bônus 10)

o=$[RANDOM%28];for i in {D..a};{ printf " %$[o+=1-2*(RANDOM%29<o)]s.%$[28-o]s
";}

Nesta resposta, o ponto é "puxado" de volta para o meio. Isso pode ser testado codificando o ponto de partida em 0 ou 30.


Boa solução! Mas por favor, não codifique o ponto de partida;)
reggaemuffin

11
@Kostronor - oops - eu perdi isso, e agora o corrigi.
Digital Trauma

2
salve um caractere substituindo {1..30}por{P..m}
Geoff Reedy

E se ofor 1e RANDOM%30retornar 0? E na próxima iteração também?
user2846289

@VadimR - Acho que as condições de contorno estão fixadas agora.
Digital Trauma

5

Ruby 69 66 64-60 = 4

i=rand(30);30.times{a=' '*30;a[i]=?.;puts a;i+=rand>i/29.0?1:-1}

Amostra:

            .             
           .              
            .             
           .              
          .               
           .              
            .             
             .            
              .           
             .            
              .           
               .          
              .           
               .          
              .           
             .            
            .             
             .            
              .           
             .            
              .           
             .            
            .             
             .            
            .             
             .            
            .             
           .              
          .               
           .              

Você pode salvar um byte em i=rand 30;vez de i=rand(30);.
Jordan

5

Smalltalk, 161 159 145-60 = 85

todas as colunas têm 30 caracteres (operando na sequência mutável b);

a chance de movimento aleatório é ajustada enviesando o valor rnd com p (rnd (0..29) -p), pegando o sinal (-1/0/1) e depois ajustando para (-1 / + 1) via (-1 | 1), que é tomado como delta de movimento (calcula efetivamente: sinal x <= 0 ifTrue: -1 ifFalse: 1). Como o ST usa a indexação baseada em 1, eu tenho que ajustar todas as referências de string em +1 (por favor, aprecie o hack de -1 | 1 bit ;-)).

p:=((r:=Random)next*29)rounded.(b:=String new:30)at:p+1put:$..0to:29do:[:i|b at:p+1put:$ .p:=(p+(((r next*29)-p)sign-1|1))min:29max:0.b at:p+1put:$..b printCR]

roubando uma ideia da versão Ruby (thanx & Up @fipgr), posso me livrar da verificação min / max:

p:=((r:=Random)next*29)rounded.(b:=String new:30)at:p+1put:$..1to:30 do:[:i|b at:p+1put:$ .p:=p+((r next-(p/29))sign-1|1).b at:p+1put:$.;printCR]

output: (Adicionei manualmente os números de coluna e as barras verticais; o código acima não os gera)

 012345678901234567890123456789
|                     .        |
|                    .         |
|                   .          |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|                 .            |
|                .             |
|               .              |
|                .             |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|               .              |
|                .             |
|               .              |
|                .             |
|               .              |
|              .               |
|               .              |
|              .               |
 012345678901234567890123456789

4

C, 86

Supondo que a propagação da rand()função não seja necessária.

k=30;main(i){i=rand()%k;while(k--){printf("%*c\n",i+=i==30?-1:i==1||rand()%2?1:-1,46);}}

Explicação:

Em C, "%*c"nos *meios que o comprimento da saída irá ter um comprimento mínimo, e este comprimento mínimo é determinado pelo argumento da chamada de função (neste caso, ele é i+=i==30?-1:i==1||rand()%2?1:-1. Os cmeios do próximo argumento ( 46) é um personagem ( o ponto).

Quanto à verificação de limites, peço desculpas por ter esquecido disso. Eu agora adicionei isso à resposta, ao custo de 15 caracteres. O operador ternário funciona da seguinte maneira: boolean_condition?value_if_true:value_if_false. Observe que em C verdadeiro é 1 e falso é 0.


Você pode expandir o que está acontecendo no seu código? Estou tendo problemas para entender como printf("%*c\n",i+=rand()%2?1:-1,46)os espaços são impressos, bem como evita que o ponto passe dos 29. Agradecemos antecipadamente. (Desculpe, eu não sou um programador em C.) #
1289 Decent Dabbler

@fireeyedboy done, espero que você entenda :) #
11005 user12205

Aaaah, eu meio que tive a sensação de que você estava trapaceando um pouco lá. ;-) Mas o resto está claro agora. Obrigado! E boa solução! C também tem um comportamento estranho, rand()%2pois é muito previsível (curvas pares / ímpares)? Eu tentei o seu rand()%2na minha solução PHP, e ele exibiu esse comportamento muito previsível (ao contrário rand(0,1). Como o PHP faz muito uso das bibliotecas C (se eu estiver correto), eu queria saber se o seu programa C tem a mesma 'falha' .
digno Dabbler

@fireeyedboy Eu não propaguei a rand()função. Em C, se rand()não for propagado explicitamente, ele sempre usa a mesma semente todas as vezes. É por isso que é previsível. Se eu tivesse a semente que eu posso fazer srand(time());que custa 14 caracteres
user12205

Mas é tão previsível que também muda de ímpar para par em cada chamada subsequente? As declarações do PHP rand()não precisam mais ser propagadas srand(), mas ainda mostram esse comportamento estranho .
Digno Dabbler

4

Java: 204 183 182 176 175 caracteres - 10 - 50 = 115

class K{public static void main(String[]y){int k,j=0,i=(int)(29*Math.random());for(;j++<30;i+=Math.random()*28<i?-1:1)for(k=0;k<31;k++)System.out.print(k>29?10:k==i?'.':32);}}

Primeiro, a posição do ponto deve ser 0 < x < 30, ou seja, [1-29]. Isso gera um número entre 0 e 28 distribuído uniformemente e, para os propósitos deste programa, [0-28] tem o mesmo efeito que [1-29]:

i=(int)(29*Math.random());

Pessoalmente, preferi que fosse distribuído normalmente por volta dos 14 anos, mas minha resposta seria mais longa:

i=0;for(;j<29;j++)i+=(int)(2*Math.random());

Segundo, esse código garante que ele tende a estar no meio:

i+=Math.random()*28<i?-1:1

A probabilidade de obter +1 é maior, pois menor é o valor de i, e temos o oposto de -1. Se ifor 0, a probabilidade de obter +1 é 100% e a probabilidade de obter -1 é 0%. Se ifor 28, o oposto disso acontecerá.

Terceiro, substituindo o 32no final por '_'para ver a saída mais fácil, vemos que cada linha tem 30 caracteres mais uma nova linha:

__________.___________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
____________._________________
_____________.________________
______________._______________
_____________.________________
______________._______________
_______________.______________
______________._______________
_____________.________________

Agradecemos a @VadimR (agora, user2846289) por apontar um mal-entendido em uma versão anterior.

Obrigado a @KevinCruijssen por cortar 6 caracteres, mesmo depois de mais de dois anos e meio depois que esta resposta foi postada inicialmente.


Mas ichegar 0é ilegal, não é?
user2846289

@VadimR, para mim iestá no intervalo [0-29]. Isso é equivalente a [1-30] ou [288-317], a saída seria a mesma. O que importa é que existem 30 números inteiros no intervalo [0-29].
Victor Stafusa

"O número de espaços é a posição x do seu ponto definido com 0 <x <30" Ou seja, o número de espaços (ou a posição do ponto com base em 0) é 1..29. inão pode ser 0. Eu entendo que é tudo sobre se divertir, mas ainda é triste.
user2846289

@VadimR, Oh, obrigado. Fixo. Isso significa que o ponto nunca estará na posição mais à direita, mas, de qualquer maneira, foi o que foi especificado.
Victor Stafusa

Sinto muito, mas não consertou nada. Imagine que irecebe 1inicialmente, e na primeira iteração Math.random()é 0, em seguida, irecebe 0. Por favor, não me interpretem mal, não se trata da sua resposta. Antes, sobre minha incapacidade de ler a maioria dos idiomas que não sejam do tipo C. Então, sem reação (exceto votos positivos) sobre erros, como posso saber se eles estão certos ou não?
user2846289

3

Mathematica 157-10-50 = 97

Um número aleatório de 1 a 30 é usado para iniciar. Todos os números de colunas restantes do ponto são escolhidos via RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, que se traduz em: "Se o número da coluna anterior for maior que 15, selecione um número no conjunto {-1,1}, com -1 ponderado 2: 1 em relação a 1; caso contrário, gire os pesos e escolha entre o mesmo conjunto.

ReplacePart substitui o elemento em uma lista de 30 espaços em branco que correspondem à coluna de interesse.

f@c_ := Switch[d = RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, 1, 2, 30, 29, d, d]
Row@ReplacePart[Array["_" &, 29], # -> "."] & /@ NestList[f, RandomInteger@29+1, 30] // TableForm

ponto


Bom uso deRandomChoice[]
Dr. belisarius

3

> <>, 358 - 10 = 348

Isso não vai ganhar no codegolf, mas funciona. (No Windows 7 com esse intérprete , que implementa a instrução "p" de maneira diferente da definida pela página esolang)

1v        >a"                              "v
v<      0<} vooooooooooooooooooooooooooooooo<
&  _>   v : >$" "@p1+:2f*(?v;
  |x1>  v^}!               <
  |xx2> v p
  |xxx3>v  
  |xxxx4v $
>!|xxx< v }
  |xxxx6v }
  |xxx7>v @
  |xx8> v :
  |x9v  < @>  5)?v$:67*)?vv
   _>>&?v!@^     >$:b(?v v
  v }"."< :        v+ 1<  <
  >a+b+00}^0}}${"."< <- 1<

O nome desse idioma não pode ser pesquisado no Google, então aqui está o artigo esolang para os curiosos.


Você pode codificar o requisito para -50 em menos de 50 caracteres?
Victor Stafusa

11
@ Victor Provavelmente, mas> <> é uma dor gigante para codificar (uma dor gigante divertida), então eu preciso dar um tempo nela.
18414 SirCxyrtyx

@SirCxyrtyx isso me fez rir. Bem, senhor do golfe.
Gusdor 19/02

3

PHP, 118 113 112 111 (, -10 pontos de bônus = 101)

(segunda tentativa, com rand()comportamento terrivelmente previsível e um pouco mais de eficiência)

for($n=30,$i=rand(1,29),$t=$s=pack("A$n",'');$n--;$i+=$i<2|rand()%2&$i<28?1:-1,$t=$s){$t[$i-1]='.';echo"$t\n";}

Resultado possível:

______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________
______._______________________
_____.________________________

PHP, 130 (, -10 pontos de bônus = 120)

(primeira tentativa)

Provavelmente isso ainda pode ser muito mais eficiente:

for($n=30,$i=rand(1,29),$t=$s=str_repeat(' ',$n)."\n";$n--;$i=$i<2?2:($i>28?28:(rand(0,1)?$i+1:$i-1)),$t=$s){$t[$i-1]='.';echo$t;}

Se eu substituir o espaço por um sublinhado (para fins de exibição), este é um resultado possível:

________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_______.______________________
______._______________________
_____.________________________
____._________________________
_____.________________________
____._________________________
___.__________________________

Curiosamente, se eu substituir rand(0,1)pelo rand()%2(PHP 5.4, no Windows XP), o resultado aleatório sempre muda de ímpar para par e vice-versa, a cada próxima iteração, tornando-o rand()preocupante e previsível, nesse sentido, de repente. Esse 'bug' parece ser um conhecido desde 2004 . Não tenho certeza se é exatamente o mesmo 'bug'.


3

J 42 caracteres - 50 -10 = -18

'_.'{~(|.~((I.%<:@#)*@-?@0:))^:(<@#)1=?~30

Explicação, começando pela direita (alguns conhecimentos sobre trens são úteis):

init=: 0=?~30          NB. where is the 0 in the random permutation of [0,29]
rep =: ^:(<@#)         NB. repeat as many times as the array is long, showing each step

rnd =: ?@0:            NB. discards input, generates a random number between 0 and 1

signdiff =: *@-        NB. sign of the difference (because this works nicely with
                       NB. the shift later on).

left_prob =: (I.%<:@#) NB. probability of shifting left. The position of the one (I.) divided by the length -1.

shift =: |.~           NB. x shift y , shifts x by y positions to the left.

output =: {&'_.'       NB. for selecting the dots and bars.

NB. Piecing things together:
output (shift (left_prob signdiff rnd))rep init

Tendência central, -50, exemplo em 1000 execuções:

NB. Amounts of ones in each column (sum)
   ]a=:+/ (|.~((I.%<:@#)*@-?@0:))^:(<1000)0=?30
0 0 0 0 0 0 2 6 10 12 25 60 95 121 145 161 148 99 49 27 19 13 6 1 1 0 0 0 0 0
   +/a NB. check the number of ones in total
1000
   |. |:(<.a%10) #"0 1] '*' NB. plot of those values
           *              
           *              
          ***             
          ***             
         ****             
         ****             
         ****             
        ******            
        ******            
        ******            
       *******            
       *******            
       ********           
       ********           
      **********          
    **************        

Exemplo de execução, produzindo exatamente 30 bytes por linha

_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
_____________.________________
____________._________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________

Uma solução muito boa!
Reggaemuffin

Um desafio muito bom também!
Jpjacobs

3

Python 2.7: 126 109 -10-50 = 49

Livre-se do ponto de partida codificado - agora começa em ponto aleatório. Por causa disso, eu precisava de randint, então decidi usá-lo em vez da escolha para o deslocamento. Utilizou o truque bool (-1) ** para isso.

from random import randint as r;p=r(0,29)
for i in range(30):
 print' '*p+'.'+' '*(29-p);p+=(-1)**(r(0,29)<p)

Algumas ótimas respostas aqui. Primeira tentativa em Python, pensando em melhorias. Não é ajudado pela necessidade de uma importação.

-10 - sim 30 caracteres + \ n em cada linha

-50 - quanto mais longe do centro, maior a probabilidade de um movimento para o outro lado (realizado através da construção de uma lista com um número diferente de + / i deslocamentos)

Tentativa anterior:

from random import choice;p,l=15,[]
for i in range(30):
 q=29-p;l+=[' '*p+'.'+' '*q];p+=choice([1]*q+[-1]*p)
print'\n'.join(l)

Seu forloop pode estar em uma linha, mas ainda melhor for i in[0]*30:e melhor ainda eval"..."*30.
mbomb007

2

Java - 198 183 caracteres

Este é apenas um exemplo claro, simples, direto e não criativo do exemplo que você deu na pergunta.

class A{public static void main(String[]y){int c,j,i=(int)(Math.random()*30);for(c=30;c>0;c--)for(j=i+=i<2?1:i>28?-1:Math.random()>0.5?1:-1;j>=0;j--)System.out.print(j>0?" ":".\n");}}

2

Lote - (288 bytes - 10) 278

@echo off&setlocal enabledelayedexpansion&set/ap=%random%*30/32768+1&for /l %%b in (1,1,30)do (set/ar=!random!%%2&if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !p! LSS 30 (set/ap+=1)else set/ap-=1
for /l %%c in (1,1,30)do if %%c==!p! (set/p"=."<nul)else set/p"=_"<nul
echo.)

Sem golfe:

@echo off
setlocal enabledelayedexpansion
set /a p=%random%*30/32768+1
for /l %%b in (1,1,30) do (
    set /a r=!random!%%2
    if !r!==1 (
        if !p! GTR 1 (set /a p-=1) else set /a p+=1
    ) else if !p! LSS 30 (set /a p+=1) else set /a p-=1
    for /l %%c in (1,1,30) do if %%c==!p! (set /p "=."<nul) else set /p "=_"<nul
    echo.
)

Para gerar espaços em vez de sublinhados - 372 bytes -

@echo off&setlocal enabledelayedexpansion&for /f %%A in ('"prompt $H &echo on&for %%B in (1)do rem"')do set B=%%A
set/ap=%random%*30/32768+1&for /l %%b in (1,1,30)do (set/ar=!random!*2/32768+1&if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !p! LSS 30 (set/ap+=1)else set/ap-=1
for /l %%c in (1,1,30)do if %%c==!p! (set/p"=."<nul)else set/p"=.%B% "<nul
echo.)

Procurando alguma ajuda com a seguinte lógica, certamente esse não é o método com mais espaço eficiente (! R! Será expandido para 1 ou 2) -

if !r!==1 (
    if !p! GTR 1 (set /a p-=1) else set /a p+=1
) else if !p! LSS 30 (set /a p+=1) else set /a p-=1

Golfe: if !r!==1 (if !p! GTR 1 (set/ap-=1)else set/ap+=1)else if !r! LSS 30 (set/ap+=1)else set/ap-=1


2

J, 42 caracteres, sem bônus

' .'{~(i.30)=/~29<.0>.+/\(-0&=)?(,2#~<:)30

Exemplo de execução:

          ' .'{~(i.30)=/~29<.0>.+/\(-0&=)?(,2#~<:)30
                       .
                      .
                     .
                      .
                     .
                      .
                     .
                      .
                       .
                      .
                     .
                    .
                     .
                    .
                     .
                    .
                     .
                      .
                       .
                        .
                       .
                        .
                       .
                      .
                     .
                      .
                       .
                      .
                     .
                    .

2

Python 2.7 (126 - 10 (comprimento da correção) - 50 (Tendência central) = 66)

O programa a seguir tem uma tendência central em uma amostra maior

s=id(9)%30
for e in ([[0,2][s>15]]*abs(s-15)+map(lambda e:ord(e)%2*2,os.urandom(30)))[:30]:
    s+=1-e;print" "*s+"."+" "*(28-s)

Demo

         .           
        .            
       .             
      .              
     .               
      .              
       .             
        .            
         .           
          .          
           .         
          .          
           .         
          .          
         .           
        .            
       .             
        .            
       .             
      .              
     .               
      .              
       .             
      .              
     .               
    .                
   .                 
    .                
   .                 
    .              

Como s = id (9)% 30 para a semeadura. OS precisa importar, no entanto? E isso cobre toda a faixa de 1 a 30? Oh, espere ... * releia a desigualdade no topo da página *
psion5mx 18/02

2

Javascript 125 73 72 60 (120 - 50 - 10)

i=0;r=Math.random;s=r()*30|0;do{a=Array(30);a[s=s>28?28:s?r()<s/30?s-1:s+1:1]='.';console.log(a.join(' '))}while(++i<30)

EDIT: Correção para bônus de 50 pontos e bônus de 10 pontos.

EDIT 2: Ainda mais curto!


você pode explicar onde consegue o bônus de 50 pontos? Eu não estou recebendo-o no momento ...
reggaemuffin

@ Kostronor Acabei de ver a edição do requisito. Parece que ainda não recebi os 50 pontos.
aebabis

@acbabis, muito bem! Você pode salvar alguns bytes (116):r=Math.random;s=r()*30|0;for(i=0;i++<30;a=Array(30)){a[s=s>28?28:s?r()<s/30?s-1:s+1:1]='.';console.log(a.join(' '))}
Michael M.

@ Michael Obrigado pelas dicas. Não foi possível obter o init da matriz dentro do fortrabalho; teve que fazer um tempo.
aebabis

2

D - 167, 162, 144 (154 - 10)

Golfe :

import std.stdio,std.random;void main(){int i=uniform(1,30),j,k;for(;k<30;++k){char[30]c;c[i]='.';c.writeln;j=uniform(0,2);i+=i==29?-1:i==0?1:j==1?1:-1;}}

Sem golfe :

import std.stdio, std.random;

void main()
{
    int i = uniform( 1, 30 ), j, k;

    for(; k < 30; ++k )
    {
        char[30] c;
        c[i] = '.';
        c.writeln;
        j = uniform( 0, 2 );
        i += i == 29 ? -1 : i == 0 ? 1 : j == 1 ? 1 : -1;
    }
}

EDIÇÃO 1 - Não tenho certeza se meu código se qualifica para o bônus -50 ou não. inem sempre começar no meio, mas durante o forciclo, o ponto nunca se move mais do que como 3 lugares qualquer direção, por isso, quando i se começar perto do meio, a coisa toda tende a ficar lá também.

EDIT 2 - O código agora se qualifica para o bônus -10, pois imprime uma matriz de 29 caracteres seguida por LF para um total de exatamente 30 caracteres por linha.


como imprime uma matriz de 29 caracteres seguida por LF - deve ter 30 caracteres seguidos por um LF.
Victor Stafusa

@ Victor ahh, obrigado pela correção, eu interpretei mal o post principal.
Tony Ellis

2

PowerShell, 77 - 10 - 50 = 17

$x=random 30
1..30|%{$x+=random(@(-1)*$x+@(1)*(29-$x))
'_'*$x+'.'+'_'*(29-$x)}

Resultado

_.____________________________
__.___________________________
___.__________________________
____._________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
______._______________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________

Aleatório inteligente. Você poderia usar uma versão em golfe $x=random 30;1..30|%{' '*($x+=,-1*$x+,1*(29-$x)|random)+'.'|% *ht 30}. 66 bytes - 10 - 50 = 6 pontos
mazzy

2

R, 107 caracteres - bônus de 60 pontos = 47

s=sample;i=s(29,1);for(j in 1:30){a=rep(' ',30);i=i+s(c(-1,1),1,p=c(i-1,29-i));a[i]='.';cat(a,'\n',sep='')}

ié o índice do ponto. aé a matriz de 30 espaços. O ponto de partida é aleatório (uniformemente de 1 a 29). Em cada iteração, adicionamos aleatoriamente -1 ou +1 a icom probabilidades ponderadas: i-1for -1e 29-i for +1(os valores alimentados como probabilidades não precisam somar uma), o que significa que ele tende a orientar o ponto em direção ao centro, impedindo-o de baixo 1 ou acima de 29 (desde que a probabilidade caia para 0 em ambos os casos).

Exemplo executado com _espaços em vez de legibilidade:

> s=sample;i=s(1:30,1);for(j in 1:30){a=rep('_',30);i=i+s(c(-1,1),1,p=c(i-1,29-i));a[i]='.';cat(a,'\n',sep='')}
_______________________.______
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
___________________.__________
____________________._________
___________________.__________
__________________.___________
_________________.____________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________

Se não me engano ao ler seu código, i pode ser um 0ou outro 30, não?
user2846289

Sim, você está certo, pode ser 30 (embora não mais), vou mudar isso.
plannapus

11
Está consertado agora. A probabilidade de ir de 1 para 0 ou de ir 29-30 é agora 0. O ponto de partida é agora aleatório entre 1 e 29.
plannapus

Dica: você pode salvar mais 2 caracteres substituindo s(1:29,1)por s(29,1).
Sven Hohenstein

@SvenHohenstein você está estou certo sempre esquecer que um
plannapus

2

C # 184 - 10 - 50 = 123

using System;namespace d{class P{static void Main(){var r=new Random();int p=r.Next(30);for(int i=0;i<30;i++){Console.WriteLine(".".PadLeft(p+1).PadRight(29));p+=r.Next(30)<p?-1:1;}}}}

Resultado

spacesubstituído _por legibilidade.

____________.________________
___________._________________
__________.__________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
___________._________________
____________.________________
___________._________________
__________.__________________
___________._________________

Tenho certeza de que deve ser possível obter um código menor if...else if...elseno final do código. Além disso, sua saída me faz duvidar de que tende a estar no meio, mas seu código parece estar correto.
Victor Stafusa

Esqueci de atualizar a saída quando editei o código. O r.Next(30)<p?-1:1;faz acontecer. Não tenho certeza se você pode ir menor com as ifinstruções. switché grande por causa do obrigatório break/ returne a final elseexige um default:{}caso e que também é longo.
Gusdor 18/02

@ Victor obrigado pela entrada. eu fiz algumas edições.
Gusdor 18/02

Se pfor zero, o valor p+=r.Next(30)<p?-1:1;sempre será 1; portanto, não é necessário if(p==0). O mesmo vale para p==29. pnunca terá 30 anos, então você pode se livrar do else if.
Victor Stafusa

@ Victor grand. vou fazer essas mudanças. Ta.
Gusdor

1

PHP

Com o bônus de centralização: 82 - 50 = 32

$i=rand(0,29);for($c=0;$c++<30;rand(0,28)<$i?$i--:$i++)echo pack("A$i",'').".\n";

Para esta versão (versões antigas abaixo), remova a verificação de mínimo / máximo, conforme o código de centralização. rand(1,28)torna-se importante aqui, pois permite o $i++aumento de até 29 (máximo real).

editar: parênteses desnecessários, código de deslocamento movido


Algoritmo simples de centralização: gera um novo número entre 0 e 29 e o compara ao atual. Aproveita a "probabilidade" de obter um número do lado maior para desenhar em direção ao centro.

Resultado real: (numeração de linha adicionada posteriormente)

01|        .
02|       .
03|        .
04|         .
05|          .
06|           .
07|            .
08|           .
09|            .
10|             .
11|              .
12|             .
13|            .
14|             .
15|            .
16|             .
17|            .
18|             .
19|              .
20|               .
21|              .
22|             .
23|              .
24|               .
25|                .
26|               .
27|                .
28|                 .
29|                .
30|               .

Arquivado:

$i=rand(0,29);for($c=0;$c++<30;){($i<1?$j=1:($i>28?$j=28:$j=rand(0,29)));($j<$i?$i--:$i++);echo pack("A$i",'').".\n";} 119 caracteres

$i=rand(0,29);for($c=0;$c++<30;){($i<1?$i++:($i>28?$i--:(rand(0,29)<$i?$i--:$i++)));echo pack("A$i",'').".\n";} 112 caracteres


Eu estou um pouco impressionado que eu raspado 49 caracteres desde a minha primeira versão ...
Yoda

raspou 44 caracteres agora. O que deve significar que foram 39 da última vez.
Yoda

1

JavaScript ES6 125 - 10 (30 linhas de caracteres) - 50 (muda para o meio) = 65

Eu tive uma epifania subindo o elevador até a minha unidade, então tive que descer antes que deixasse minha memória ...

z=(j=Array(t=29).join`_`)+"."+j;x=(r=Math.random)()*t;for(i=30;i--;)console.log(z.substr(x=(x+=r()<x/t?-1:1)>t?t:x<0?0:x,30))

Um pouco de shuffling posicional variável e um pouco de criatividade para calcular a probabilidade de deslocamento indicada por x/t... (Obrigado Kostronor por apontá-lo!) Agora, ganho o bônus de -50 por deslocamento para o meio e também fiz a posição inicial dentro do gama completa da linha, o que me permitiu barbear dois bytes!

....5....0....5....0....5....0 <-- Ruler
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
__.___________________________
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________

Não é que a aleatoriedade da posição inicial do ponto aqui seja limitada a 2 ou 3 possibilidades? E é isso que manter o ponto no meio (por causa do número muito curto de execuções = 30) e, portanto, vale -50?
user2846289

Citando o texto do OP : "Seu programa começa com uma posição x aleatória e a cada turno muda essa posição aleatoriamente de 1 para a esquerda ou direita". Meu código é inicialmente definido no 15+r()*2qual pode haver algo entre 15 e 16.9999999998 ou mais que possa arredondar para 17. o adicional x+=r()<.5?-1:1lança um pouco mais de aleatoriedade, elevando-o para um intervalo de 14 a 18, portanto, tecnicamente, um número aleatório que está dentro da definição do que foi solicitado ... Ao dobrar essa regra, o flip (+1, -1), na maioria dos casos trazê-lo de volta para o meio ...;)
Wally West

Bem, por acaso, você me entendeu ... Era para ser 'uma posição aleatória de todas as posições possíveis', mas não oferece muita vantagem, pois os 50 pontos claramente não se aplicam! Releia a explicação sobre esse bônus; 0,5% fixo não o recebe!
Reggaemuffin

Ponto válido, vou refazer minha pontuação de acordo ...
WallyWest 20/02

@ Kostonor Code atualizado com solução adequada, pontuação atualizada de acordo!
Wally West

1

k, 53 - 10 - 50 = -7

Solução 1

{{a:30#" ";a[x]:".";a}'{x+$[*x<1?!30;1;-1]}\[x;*1?x]}

Uso

{{a:30#" ";a[x]:".";a}'{x+$[*x<1?!30;1;-1]}\[x;*1?x]}30

"      .                       "
"       .                      "
"      .                       "
"       .                      "
"      .                       "
"       .                      "
"        .                     "
"         .                    "
"        .                     "
"         .                    "
"        .                     "
"         .                    "
"          .                   "
"           .                  "
"            .                 "
"             .                "
"              .               "
"               .              "
"              .               "
"             .                "
"            .                 "
"           .                  "
"          .                   "
"         .                    "
"        .                     "
"       .                      "
"        .                     "
"         .                    "
"          .                   "
"         .                    "
"          .                   "

Solução 2

{r::x;{a:r#" ";a[x]:".";a}'{a:r#0b;a[x?r]:1b;x+$[a@*1?r;-1;1]}\[x;*1?x]}[30]

1

Scala, 95 - 10 = 85 bytes

def r=math.random
Seq.iterate(r*30,30){n=>println(("#"*30)updated(n.toInt,'.'))
(r*2-1+n)round}

Ainda estou pensando no bônus de 50 bytes.

Explicação:

def r=math.random //define a shortcut for math.random, which returns a number 0 <= n < 1
Seq.iterate(      //build a sequence,
  r*30,             //starting with a random number bewteen 0 and 29
  30                //and containing 30 elements.
){n=>             //Calculate each element by applying this function to the previous element
  println(        //print...
    (" "*30)             //30 spaces
    updated(n.toInt,'.') //with the n-th char replaced with a dot
  )               //and a newline.
                  //The next element is
  (r*2-1+n)       //an random number between -1 and 1 plus n
  round           //rounded to the nearest integer.
}

1

Javascript, 125 (135 - 10)

q=Math.random,p=~~(q()*31)+1;for(i=0;i++<30;){s='',d=j=1;for(;j++<31;)s+=j==p?'.':" ";p+=q()<.5?1:-1;p-=p>28?2:p<2?-2:0;console.log(s)}

Comentários e conselhos são bem-vindos.


Infelizmente, sua solução não se qualifica, compare sua saída com a saída de outras soluções. Mude o ponto por um caractere.
Reggaemuffin

@Kostronor Oh! ah! Eu sinto muitíssimo! Eu esqueci de ler essa parte da pergunta! Vou tentar desenvolver uma nova versão em breve. Obrigado por apontar!
Gaurang Tandon

Programa @Kostronor editado.
Gaurang Tandon

1

Javascript

114 caracteres - 10 (30 linhas de caracteres) - 50 (puxe o ponto para o meio) = 54

for(f=Math.random,a=[],i=30,j=k=f()*i|0;i--;a[j]='.',a[j+=29-k]='\n',j+=k+=f()>k/29?1:-1);console.log(a.join('-'))

No entanto, notei que uma recompensa de 10 caracteres por preencher as linhas com 30 caracteres pode ser um mau negócio; assim:

102 caracteres - 50 (puxe o ponto para o meio) = 52

for(f=Math.random,a=[],i=30,j=k=f()*i|0;i;i--,a[j]='.\n',j+=k+=f()>k/29?1:-1);console.log(a.join('-'))

Parabéns a @WallyWest pela condição de direção de extração simplificada f()>k/29?1:-1, meu primeiro rascunho usou duas condicionais aninhadas.


1

Raquete 227 bytes (-10 para 30 caracteres, -50 para deslocamento para a linha média = 167)

A cada passo, o ponto tem duas vezes mais chances de se mover para a linha média do que para longe dele:

(let lp((r(random 1 31))(c 0)(g(λ(n)(make-string n #\space))))(set! r
(cond[(< r 1)1][(> r 30)30][else r]))(printf"~a~a~a~n"(g r)"*"(g(- 29 r)))
(when(< c 30)(lp(+ r(first(shuffle(if(> r 15)'(-1 -1 1)'(1 1 -1)))))(add1 c)g)))

Ungolfed:

(define (f)
    (let loop ((r (random 1 31))
               (c 0)
               (g (λ (n) (make-string n #\space))))
      (set! r (cond
                [(< r 1) 1]
                [(> r 30) 30]
                [else r] ))
      (printf "~a~a~a~n" (g r) "*" (g (- 29 r)))
      (when (< c 30)
        (loop (+ r
                 (first
                  (shuffle
                   (if (> r 15)
                       '(-1 -1 1)
                       '(1 1 -1)))))
              (add1 c)
              g))))

Teste:

(println "012345678901234567890123456789")
(f)

Resultado:

"012345678901234567890123456789"
                       *       
                      *        
                       *       
                        *      
                         *     
                        *      
                       *       
                      *        
                     *         
                      *        
                     *         
                    *          
                     *         
                      *        
                     *         
                    *          
                   *           
                  *            
                 *             
                *              
               *               
                *              
                 *             
                *              
                 *             
                *              
                 *             
                *              
                 *             
                *              
               *               

Ótima solução! A raquete é realmente interessante. Você pode dar-se os 50 pontos de bônus e verificar se você aplicar para o adicional de 10 :-)
reggaemuffin
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.