El punto cambiante

16

Su programa tiene que imprimir varios espacios, seguidos de un punto y una nueva línea. El número de espacios es la posición x de su punto definido con 0 <x <30

Cada nueva línea es un turno. Su programa se ejecuta durante 30 turnos. Su programa comienza con una posición x aleatoria y cada giro cambia esta posición aleatoriamente en 1 a la izquierda o derecha, mientras permanece dentro del área definida. Cada vez que su punto tiene que cambiar su posición por 1.

Tu puntuación es la cantidad de caracteres. Obtiene 10 puntos de bonificación, si cada línea impresa consta de exactamente 30 caracteres (y nueva línea). Obtiene 50 puntos de bonificación si, si bien es aleatorio, su programa tiende a permanecer en el centro del área definida.

Editar: Los 50 puntos de bonificación están destinados a tirar de su punto hacia el medio. Por ejemplo, esto se aplica si su punto está en x = 20 y tiene una probabilidad de 66% de ir a la izquierda y 33% de ir a la derecha. Esto tiene que ser independiente del punto de partida y solo debe suceder alterando el valor porcentual de izquierda / derecha dinámicamente.

No se permite ninguna entrada de ningún tipo, ¡la salida debe estar en la consola de ejecución!

Para una mejor comprensión, aquí hay un ejemplo legible en Java, que le daría una puntuación 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('.');
    }
}
reggaemuffin
fuente
En su ejemplo, creo que int i = (int)(Math.random()*30);debería ser int i = 1 + (int)(Math.random()*29);en su lugar. Como es, genera un número en 0 >= x > 30lugar de 0 > x > 30.
Victor Stafusa
Creo que el código original es correcto.
usuario2846289
es correcto, porque primero cambio y la impresión. así que incluso si el valor aleatorio excede el borde, primero se corregirá y luego se imprimirá.
reggaemuffin
@Kostronor Pero esto implica que la posición del punto inicial no sigue una distribución uniforme, la primera posición es dos veces más probable que las otras posiciones. OTOH, tampoco se requería una distribución uniforme.
Victor Stafusa
Parece que sería más difícil crear un programa donde el punto salta más. Entonces, ¿por qué hay una bonificación por restringir su movimiento?
Chris Laplante

Respuestas:

18

APL, 39-10-50 = –21

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

Probado en Dyalog con ⎕IO←1y, ⎕ML←3pero debería ser bastante portátil.

Explicación

                   ?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

En cada paso, este código decide si mover el punto hacia la izquierda o hacia la derecha dependiendo de la probabilidad de que un número aleatorio elegido entre (1.5 2.5 ... 27.5 28.5) sea menor que la posición actual del punto.

Por lo tanto, cuando la posición actual del punto (número de espacios a la izquierda) es 1, el incremento siempre es +1 (todos esos números 1.5 ... 28.5 son> 1), cuando es 29 siempre es -1 (todos esos números son <29); de lo contrario, se elige al azar entre +1 y -1, con una probabilidad de que sea una interpolación lineal entre esos extremos. Entonces, el punto siempre se mueve y siempre es más probable que se mueva hacia el centro que hacia los lados. Si está exactamente en el medio, tiene un 50% de posibilidades de moverse a cualquier lado.

La reducción (plegado a la derecha) de un valor replicado {...}/a/bes solo un truco que se me ocurrió para repetir los a-1tiempos de una función , comenzando con el valor by haciendo que el resultado de cada iteración sea el argumento del acumulador ( ) para el siguiente. Se ignoran los argumentos de entrada segundo y siguiente ( ), así como el resultado final. Resulta ser mucho más corto que una llamada recursiva regular con guardia.

Ejecución de ejemplo

0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29
                   .          
                    .         
                   .          
                  .           
                 .            
                .             
               .              
                .             
               .              
                .             
               .              
              .               
             .                
              .               
             .                
              .               
               .              
              .               
               .              
                .             
                 .            
                  .           
                 .            
                  .           
                 .            
                  .           
                 .            
                .             
               .              
                .             
Tobia
fuente
apl es un gran lenguaje para el golf (aunque difícil de leer para mí); ¡ARRIBA!
blabla999
@ blabla999 APL tiene muchos símbolos comunes y algunos extraños, pero una vez que aprende su función, el lenguaje es fácil de leer y escribir. Ciertamente más fácil que el ruido ASCII de los idiomas de "golf", pero me atrevería a decir que es aún más fácil que los idiomas normales. La sintaxis es muy regular, solo tiene una regla: las expresiones se ejecutan de derecha a izquierda, para que puedan leerse de izquierda a derecha: +/2×⍳9se lee "la suma de: dos veces: los naturales hasta 9" pero es ejecutado de manera opuesta.
Tobia
¿Soy yo o hay 31 caracteres por línea aquí?
Gusdor
Obtengo 30, copiando y pegando una línea del ejemplo anterior en un editor, y comprobando el código nuevamente. ⎕←30↑...imprimirá 30 caracteres más una nueva línea, sin importar en qué cadena esté...
Tobia
12

Mathematica 138 - 10 - 50 = 78

No estoy publicando esto porque creo que está particularmente bien golfizado, pero por otras razones. Utiliza un proceso de Markov definición de con una matriz de transición diseñada para "centrar" la pelota.

El uso de un proceso de Markov en Mathematica nos permite calcular algunas estadísticas útiles , como verá a continuación.

Primero el código (espacios no necesarios):

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

Algunas salidas:

Gráficos de Mathematica

La matriz de transición que utilicé es:

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

Gráficos de Mathematica

Pero como dije, la parte interesante es que usar DiscreteMarkovProcess[] nos permite tomar una buena imagen de lo que está sucediendo.

Veamos la probabilidad de que la pelota esté 15en cualquier momento a t partir de un estado aleatorio particular :

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 de Mathematica

Puede ver que fluctúa entre 0 y un valor cercano a 0.3, eso se debe a que, dependiendo del estado inicial, solo puede alcanzar 15 en un número impar o par de pasos :)

Ahora podemos hacer lo mismo, pero diciéndole a Mathematica que considere la estadística a partir de todos los estados iniciales posibles. ¿Cuál es la probabilidad de estar 15después de un tiempo 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 de Mathematica

Puedes ver que también oscila ... ¿por qué? La respuesta es simple: en el intervalo [1, 29]hay más números impares que pares :)

La oscilación casi desaparece si preguntamos por la probabilidad de que la pelota esté en 14 OR 15:

Gráficos de Mathematica

Y también podría pedir el límite (en el sentido de Cesaro) de las probabilidades estatales:

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

Gráficos de Mathematica

Oh, bueno, tal vez merezco algunos votos negativos para una respuesta tan fuera de tema. Sentirse libre.

Dr. belisario
fuente
2
Este no es el más corto, pero es realmente genial.
Kasra Rahjerdi
Votó a favor, y ahora su puntaje ya no es 2,222 ...
cormullion
@cormullion Gracias! Puede deshacerlo votando duro :)
Dr. belisarius
7

Bash, puntaje 21 (81 bytes - 50 bonus - 10 bonus)

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

En esta respuesta, el punto se "jala" hacia el centro. Esto se puede probar codificando el punto de partida en 0 o 30.

Trauma digital
fuente
¡Buena solución! Pero por favor no codifique el punto de partida;)
reggaemuffin
1
@Kostronor - ¡Vaya! Me lo perdí y ahora lo he solucionado.
Trauma digital
2
guardar un personaje reemplazando {1..30}por{P..m}
Geoff Reedy
¿Qué pasa si oes 1y RANDOM%30vuelve 0? ¿Y en la próxima iteración también?
user2846289
@VadimR: creo que las condiciones de contorno están arregladas ahora.
Trauma digital
5

Rubí 69 66 64-60 = 4

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

Muestra:

            .             
           .              
            .             
           .              
          .               
           .              
            .             
             .            
              .           
             .            
              .           
               .          
              .           
               .          
              .           
             .            
            .             
             .            
              .           
             .            
              .           
             .            
            .             
             .            
            .             
             .            
            .             
           .              
          .               
           .              
fgp
fuente
Puede guardar un byte con en i=rand 30;lugar de i=rand(30);.
Jordan
5

Smalltalk, 161 159 145-60 = 85

todas las columnas tienen 30 caracteres de largo (operan en una cadena mutable b);

La posibilidad de movimiento aleatorio se ajusta al sesgar el valor rnd con p (rnd (0..29) -p), tomar el signo (-1/0/1) y luego ajustarlo a (-1 / + 1) a través de (-1 | 1), que se toma como mover delta (efectivamente calcula: signo x <= 0 ifTrue: -1 ifFalse: 1). Como ST usa indexación basada en 1, tengo que ajustar todas las referencias de cadena en +1 (por favor, aprecio el truco de violín -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]

Robando una idea de la versión Ruby (gracias y Up @fipgr), puedo deshacerme de la verificación 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]

salida: (he agregado manualmente los números col y las barras verticales después; el código anterior no los genera)

 012345678901234567890123456789
|                     .        |
|                    .         |
|                   .          |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|                 .            |
|                .             |
|               .              |
|                .             |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|               .              |
|                .             |
|               .              |
|                .             |
|               .              |
|              .               |
|               .              |
|              .               |
 012345678901234567890123456789
blabla999
fuente
4

C, 86

Asumiendo que rand()no se requiere sembrar la función.

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

Explicación:

En C, en "%*c"los *medios que la longitud de la salida tendrá una longitud mínima, y esta longitud mínima se determina por el argumento de la llamada de función (en este caso, es i+=i==30?-1:i==1||rand()%2?1:-1. Los cmedios de la siguiente argumento (46 ) es un personaje ( el punto).

En cuanto a la verificación de límites, me disculpo por haberme olvidado de eso. Ahora he agregado esto a la respuesta, a costa de 15 caracteres. El operador ternario funciona de la siguiente manera: boolean_condition?value_if_true:value_if_false. Tenga en cuenta que en C verdadero es 1 y falso es 0.

usuario12205
fuente
¿Puedes ampliar lo que está sucediendo en tu código? Tengo problemas para entender cómo printf("%*c\n",i+=rand()%2?1:-1,46)imprime los espacios, así como cómo evita que el punto se mueva más allá de 29. Gracias de antemano. (Lo siento, no soy un programador en C.)
Decente Dabbler
@fireeyedboy hecho, espero que lo entiendas :)
user12205
Aaaah, tuve la sensación de que estabas engañando un poco allí. ;-) Pero el resto está claro de hecho ahora. ¡Gracias! Y buena solución! ¿C también tiene el comportamiento extraño conrand()%2 en que es muy predecible (turnos pares / impares)? Probé su rand()%2en mi solución PHP, y exhibió este comportamiento muy predecible (a diferencia de rand(0,1). Dado que PHP hace mucho uso de las bibliotecas C (si estoy en lo correcto), me preguntaba si su programa C tiene el mismo 'defecto' .
Decente Dabbler
@ fireeyedboy No sembró la rand()función. En C si rand()no se siembra explícitamente, siempre usa la misma semilla cada vez. Por eso es predecible. Si tuviera que srand(time());
sembrarlo,
Pero, ¿es tan predecible que cambie de impar a par en cada llamada posterior también? Las afirmaciones de PHP rand()no necesitan ser sembradas consrand() , pero aún muestran este comportamiento extraño .
Dabbler decente
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);}}

Primero, la posición del punto debe ser 0 < x < 30, es decir, [1-29]. Esto genera un número entre 0 y 28 distribuidos uniformemente, y para los propósitos de este programa [0-28] tiene el mismo efecto que [1-29]:

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

Personalmente, prefería que se distribuyera normalmente alrededor de 14, pero mi respuesta sería más larga:

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

Segundo, este código asegura que tiende a estar en el medio:

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

La probabilidad de obtener +1 es mayor ya que menor es el valor de i, y tenemos el opuesto para -1. Si ies 0, la probabilidad de obtener +1 es 100% y la probabilidad de obtener -1 es 0%. Si ies 28, sucederá lo contrario.

Tercero, al reemplazar el 32al final por '_'para ver la salida más fácilmente, vemos que cada línea tiene 30 caracteres más una nueva línea:

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

Gracias a @VadimR (ahora, usuario 2846289) por señalar un malentendido en una versión anterior.

Gracias a @KevinCruijssen por eliminar 6 caracteres, incluso después de más de dos años y medio después de que esta respuesta se publicara inicialmente.

Victor Stafusa
fuente
Pero illegar 0es ilegal, ¿no?
user2846289
@VadimR, para mí iestá en el rango [0-29]. Esto es equivalente a [1-30] o [288-317], la salida sería la misma. Lo que importa es que hay 30 números enteros en el intervalo [0-29].
Victor Stafusa
"El número de espacios es la posición x de su punto definido con 0 <x <30" Es decir, el número de espacios (o la posición de punto basada en 0) es 1..29. iNo puede ser 0. Entiendo que se trata de divertirse, pero aún así es triste.
user2846289
@VadimR, Oh, gracias. Fijo. Esto significa que el punto nunca estará en la posición más a la derecha, pero de todos modos, eso es lo que se especificó.
Victor Stafusa
Lo siento, pero no solucionó nada. Imagine iobtiene 1inicialmente, y en la primera iteración Math.random()es 0, luego iobtiene 0. Por favor, no me malinterpretes, no se trata de tu respuesta. Más bien sobre mi incapacidad para leer la mayoría de los idiomas que no sean C-like. Luego, sin ninguna reacción (excepto los votos a favor) sobre los errores, ¿cómo puedo saber si son correctos o no?
user2846289
3

Mathematica 157-10-50 = 97

Se utiliza un número aleatorio del 1 al 30 para comenzar. Todos los números de columna restantes del punto se eligen mediante RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c , lo que se traduce en: "Si el número de columna anterior era mayor que 15, seleccione un número del conjunto {-1,1}, con -1 ponderado 2: 1 con respecto a 1; de lo contrario, voltee los pesos y elija del mismo conjunto.

ReplacePart reemplaza el elemento en una lista de 30 espacios en blanco que corresponde a la columna de interés.

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

punto

DavidC
fuente
Buen uso deRandomChoice[]
Dr. belisarius
3

> <>, 358-10 = 348

Esto no ganará en codegolf, pero funciona. (En Windows 7 con este intérprete , que implementa la instrucción "p" de forma diferente a como la define la 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<

El nombre de este idioma no se puede buscar en Google, así que aquí está su artículo de esolang para curiosos.

SirCxyrtyx
fuente
¿Puedes codificar el requisito para -50 en menos de 50 caracteres?
Victor Stafusa
1
@Victor Probablemente, pero> <> es un dolor gigante para codificar (un dolor gigante divertido), así que necesito tomar un descanso.
SirCxyrtyx
@SirCxyrtyx esto me hizo reír. Bien golfizado señor.
Gusdor
3

PHP, 118 113 112 111 (, -10 puntos de bonificación = 101)

(segundo intento, con un rand()comportamiento horriblemente predecible y un poco más de eficiencia)

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

Posible resultado:

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

PHP, 130 (, -10 puntos de bonificación = 120)

(primer intento)

Esto probablemente aún podría ser mucho más 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;}

Si reemplazo el espacio con un guión bajo (para fines de visualización), este es un posible resultado:

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

Por extraño que parezca, si lo reemplazo rand(0,1)con rand()%2(PHP 5.4, en Windows XP), el resultado aleatorio siempre cambia de impar a par, y viceversa, en cada próxima iteración, lo que hace que sea rand()preocupantemente predecible, en ese sentido, de repente. Este 'error' parece ser uno que se conoce desde 2004 . Sin embargo, no estoy completamente seguro de si es exactamente el mismo 'error'.

Dabbler decente
fuente
3

J 42 caracteres - 50-10 = -18

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

Explicación, comenzando por la derecha (algunos conocimientos sobre trenes son útiles):

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

Tendencia central, -50, ejemplo en más de 1000 carreras:

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
           *              
           *              
          ***             
          ***             
         ****             
         ****             
         ****             
        ******            
        ******            
        ******            
       *******            
       *******            
       ********           
       ********           
      **********          
    **************        

Ejemplo ejecutado, generando exactamente 30 bytes por línea

_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
_____________.________________
____________._________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________
jpjacobs
fuente
¡Una muy buena solución!
reggaemuffin
¡Un muy buen desafío también!
jpjacobs
3

Python 2.7: 126 109 -10-50 = 49

Se deshizo del punto de partida codificado, ahora comienza en un punto aleatorio. Debido a esto, necesitaba randint, así que decidí usar eso en lugar de elegir el desplazamiento. Usé el truco (-1) ** bool para eso.

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)

Algunas buenas respuestas aquí. Primer intento en Python, pensando en mejoras. No ayudado por la necesidad de una importación.

-10 - sí 30 caracteres + \ n en cada línea

-50 - cuanto más lejos del centro, más probabilidades hay de moverse hacia el otro lado (logrado mediante la creación de una lista con un número diferente de desplazamientos + / i)

Intento previo:

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)
psion5mx
fuente
Su forbucle puede estar todo en una línea, pero aún mejor es for i in[0]*30:y aún mejor eval"..."*30.
mbomb007
2

Java - 198 caracteres

Este es solo un golf simple, directo, directo y poco creativo del ejemplo que usted dio en la pregunta.

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");}}
Victor Stafusa
fuente
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.)

Sin golf:

@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 generar espacios en lugar de guiones bajos - 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.)

Buscando ayuda con la siguiente lógica, seguramente este no es el método más eficiente en cuanto al espacio (! R! Se expandirá a 1 o 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

Se juega golf a: 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

carne sin carne
fuente
2

J, 42 caracteres, sin bonificaciones

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

Ejemplo de ejecución:

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

Python 2.7 (126-10 (longitud fija) - 50 (Tendencia central) = 66)

El siguiente programa tiene una tendencia central sobre una muestra más grande

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)

Manifestación

         .           
        .            
       .             
      .              
     .               
      .              
       .             
        .            
         .           
          .          
           .         
          .          
           .         
          .          
         .           
        .            
       .             
        .            
       .             
      .              
     .               
      .              
       .             
      .              
     .               
    .                
   .                 
    .                
   .                 
    .              
Abhijit
fuente
Como el s = id (9)% 30 para la siembra. os necesita importar, sin embargo? ¿Y esto cubre el rango completo de 1-30? Oh, espera ... * vuelve a leer la desigualdad en la parte superior de la página *
psion5mx
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)

EDITAR: corrige la bonificación de 50 puntos y la bonificación de 10 puntos.

EDIT 2: incluso más corto!

aebabis
fuente
¿Puedes explicar dónde obtienes el bono de 50 puntos? No lo entiendo en este momento ...
reggaemuffin
@Kostronor Acabo de ver la edición para el requisito. Parece que todavía no obtengo los 50 puntos.
aebabis
@acbabis, ¡bien hecho! Puede guardar algunos 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 Gracias por los consejos. Sin forembargo, no se pudo obtener la matriz init dentro del trabajo; tuvo que usar un tiempo mientras.
aebabis
2

D - 167, 162144 (154-10)

Golfizado :

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

Sin golf :

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

EDITAR 1 : no estoy muy seguro de si mi código califica para el bono de -50 o no. ino siempre empieza en el medio, pero durante el forbucle, el punto no se mueve más de 3 lugares, como cualquier dirección, por lo que cuando i no empezar a cerca de la mitad, todo tiende a permanecer allí también.

EDITAR 2 : el código ahora califica para la bonificación de -10, ya que imprime una matriz de 29 caracteres seguidos de LF para un total de exactamente 30 caracteres por línea.

Tony Ellis
fuente
ya que imprime una matriz de 29 caracteres seguidos de LF : debe tener 30 caracteres seguidos de un LF.
Victor Stafusa
@Victor ahh, gracias por la corrección, interpreté mal la publicación principal.
Tony Ellis
2

PowerShell, 77-10-50 = 17

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

Salida

_.____________________________
__.___________________________
___.__________________________
____._________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
______._______________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
Rynant
fuente
Inteligente al azar. Podrías usar una versión de golf $x=random 30;1..30|%{' '*($x+=,-1*$x+,1*(29-$x)|random)+'.'|% *ht 30}. 66 bytes -
10-50
2

R, 107 caracteres - 60 puntos de bonificación = 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='')}

ies el índice del punto. aes la matriz de 30 espacios. El punto de partida es aleatorio (uniformemente del 1 al 29). En cada iteración agregamos aleatoriamente -1 o +1 icon probabilidades ponderadas: i-1para -1y 29-i para+1 (los valores alimentados como probabilidades no necesitan sumar uno), lo que significa que tiende a orientar el punto hacia el centro mientras lo evita desde abajo 1 o superior a 29 (ya que su probabilidad cae a 0 en ambos casos).

Ejemplo ejecutado con en _lugar de espacios para legibilidad:

> 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='')}
_______________________.______
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
___________________.__________
____________________._________
___________________.__________
__________________.___________
_________________.____________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
plannapus
fuente
Si no me equivoco al leer su código, ¿ i puede ser uno 0o 30no?
user2846289
Sí, tienes razón, puede ser 30 (aunque no más), lo cambiaré.
plannapus
1
Ya está arreglado. La probabilidad de ir de 1 a 0 o de 29 a 30 ahora es 0. El punto de partida aleatorio ahora está entre 1 y 29.
plannapus
Sugerencia: puede guardar 2 caracteres más reemplazándolos s(1:29,1)por s(29,1).
Sven Hohenstein
@SvenHohenstein tienes razón, siempre me olvido de eso
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;}}}}

Salida

spacereemplazado _por legibilidad.

____________.________________
___________._________________
__________.__________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
___________._________________
____________.________________
___________._________________
__________.__________________
___________._________________
Gusdor
fuente
Estoy bastante seguro de que debería ser posible obtener un código más pequeño if...else if...elseal final de su código. Además, su salida me hace dudar de que tiende a estar en el medio, pero su código parece ser correcto.
Victor Stafusa
Olvidé actualizar la salida cuando edité el código. El r.Next(30)<p?-1:1;hace que suceda. No estoy seguro de que pueda ir más pequeño con las ifdeclaraciones. switches grande debido a lo obligatorio break/ returny la final elserequiere un default:{}caso y eso también es largo.
Gusdor
@Victor gracias por el aporte. Hice algunas ediciones.
Gusdor
Si pes cero, p+=r.Next(30)<p?-1:1;siempre obtendrá 1, por lo que no es necesario if(p==0). Lo mismo para p==29. pnunca será 30, así que puedes deshacerte de él else if.
Victor Stafusa
@Victor grand. Haré esos cambios. Ejército de reserva.
Gusdor
1

PHP

Con la bonificación de centrado: 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 versión (versiones anteriores a continuación), se eliminó la comprobación mínima / máxima, ya que eso se ocupa en el código de centrado. rand(1,28)se vuelve importante aquí ya que permite la$i++ que se empuje hasta 29 (máximo real).

editar: paréntesis innecesario, código de desplazamiento movido


Algoritmo simple para centrar: genera un nuevo número entre 0 y 29 y lo compara con el actual. Aprovecha la "probabilidad" de obtener un número en el lado más grande para dibujar hacia el centro.

Resultado real: (numeración de línea agregada después)

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

Archivado:

$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

Yoda
fuente
Estoy un poco impresionado de haber eliminado 49 caracteres desde mi primera versión ...
Yoda
afeitado 44 caracteres ahora. Lo que debe significar que fue 39 la última vez.
Yoda
1

JavaScript ES6 125-10 (30 líneas de caracteres) - 50 (se desplaza hacia el centro) = 65

Tuve una epifanía subiendo por el ascensor a mi unidad, así que tuve que bajarla antes de que saliera de mi memoria ...

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

Un poco de barajado de posición variable y un poco de creatividad para calcular la probabilidad de cambio indicada por x/t... (¡Gracias Kostronor por señalarlo!) Ahora obtengo la bonificación de -50 por el cambio al medio, y también hice la posición inicial dentro del rango completo de la línea, lo que me permitió afeitar dos bytes!

....5....0....5....0....5....0 <-- Ruler
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
__.___________________________
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________
WallyWest
fuente
¿No es que la aleatoriedad de la posición inicial del punto aquí está limitada a 2 o 3 posibilidades? ¿Y eso es lo que mantiene el punto en el medio (debido al número muy corto de carreras = 30) y, por lo tanto, vale -50?
user2846289
Citando el texto del OP : "Su programa comienza con una posición x aleatoria y cada giro cambia esta posición aleatoriamente 1 a la izquierda o la derecha" Inicialmente, mi código está definido en 15+r()*2que podría ser de 15 a 16.9999999998 más o menos que podría redondear fuera a 17. los x+=r()<.5?-1:1lanzamientos adicionales arrojan un poco más de aleatoriedad al llevarlo a un rango de 14 a 18, por lo que técnicamente es un número aleatorio que está dentro de la definición de lo que se pidió ... Al doblar esa regla, el flip (+1, -1) en la mayoría de los casos lo traerá de regreso al medio ...;)
WallyWest
Bueno, en lo aleatorio, me entendiste ... ¡Estaba destinado a ser 'una posición aleatoria de todas las posiciones posibles' pero no te da mucha ventaja, ya que los 50 puntos claramente no se aplican! Vuelva a leer la explicación de este bono, ¡un 0,5 por ciento fijo no lo entiende!
reggaemuffin
Punto válido, rehaceré mi puntaje en consecuencia ...
rehaceré
¡Código @Kostonor actualizado con la solución adecuada, puntaje actualizado en consecuencia!
WallyWest
1

k, 53-10-50 = -7

Solución 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

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

Solución 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]
nyi
fuente
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}

Todavía estoy pensando en el bono de 50 bytes.

Explicación:

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.
}
corvus_192
fuente
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)}

Comentarios y consejos son bienvenidos.

Gaurang Tandon
fuente
Lamentablemente, su solución no califica, compare su salida con la salida de otras soluciones. Cambia el punto por un caracter.
reggaemuffin
@Kostronor ¡Oh! ¡Oh! ¡Lo siento mucho! ¡Olvidé leer esa parte de la pregunta! Intentaré desarrollar una nueva versión pronto. Gracias por señalar!
Gaurang Tandon
Programa @Kostronor editado.
Gaurang Tandon
1

JavaScript

114 caracteres - 10 (30 líneas de caracteres) - 50 (tire del punto hacia el centro) = 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('-'))

Sin embargo, noté que una recompensa de 10 caracteres por llenar las líneas con 30 caracteres puede ser un mal negocio; entonces:

102 caracteres - 50 (tire del punto hacia el centro) = 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('-'))

Felicitaciones a @WallyWest por la dirección de extracción simplificada condicional f()>k/29?1:-1, mi primer borrador usó dos condicionales anidados.

codeporn
fuente
1

Raqueta 227 bytes (-10 para 30 caracteres, -50 para cambio a línea media = 167)

En cada paso, es más probable que el punto se mueva hacia la línea media que lejos de él:

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

Sin golf:

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

Pruebas:

(println "012345678901234567890123456789")
(f)

Salida:

"012345678901234567890123456789"
                       *       
                      *        
                       *       
                        *      
                         *     
                        *      
                       *       
                      *        
                     *         
                      *        
                     *         
                    *          
                     *         
                      *        
                     *         
                    *          
                   *           
                  *            
                 *             
                *              
               *               
                *              
                 *             
                *              
                 *             
                *              
                 *             
                *              
                 *             
                *              
               *               
rnso
fuente
Buena solución! La raqueta es realmente interesante. Puede
otorgarse