Il punto mobile


16

Il tuo programma deve stampare un numero di spazi, seguito da un punto e una nuova riga. Il numero di spazi è la posizione x del punto definito con 0 <x <30

Ogni nuova linea è una svolta. Il tuo programma dura 30 turni. Il programma inizia con una posizione x casuale e ogni giro sposta questa posizione in modo casuale di 1 a sinistra o a destra, rimanendo all'interno dell'area definita. Ogni turno il punto deve cambiare la sua posizione di 1.

Il tuo punteggio è il numero di caratteri. Ottieni 10 punti bonus, se ogni riga stampata è composta esattamente da 30 caratteri (e nuova riga). Ricevi 50 punti bonus se, se casuale, il tuo programma tende a rimanere al centro dell'area definita.

Modifica: i 50 punti bonus hanno lo scopo di tirare il punto al centro. Ad esempio, questo vale se il tuo punto è x = 20 e ha una probabilità del 66% di andare a sinistra e del 33% di andare a destra. Questo deve essere indipendente dal punto di partenza e dovrebbe avvenire solo modificando dinamicamente il valore percentuale di sinistra / destra.

Nessun input consentito, l'output deve essere sulla console di esecuzione!

Per una migliore comprensione, ecco un esempio leggibile in Java, che ti darebbe un punteggio di 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('.');
    }
}

Nel tuo esempio, penso che int i = (int)(Math.random()*30);dovrebbe essere int i = 1 + (int)(Math.random()*29);invece. Così com'è, genera un numero 0 >= x > 30anziché 0 > x > 30.
Victor Stafusa,

Penso che il codice originale sia corretto.
user2846289

è corretto, perché io cambio prima e la stampa. quindi anche se il valore casuale supera il bordo, se prima correggerà e poi stamperà.
reggaemuffin,

@Kostronor Ma questo implica che la posizione del punto iniziale non segue una distribuzione uniforme, la prima posizione è due volte più probabile delle altre posizioni. OTOH, essere uniformemente distribuito non era neanche un requisito.
Victor Stafusa,

Sembra che sarebbe più difficile creare un programma in cui il punto salta di più. Quindi perché c'è un bonus per limitare i suoi movimenti?
Chris Laplante,

Risposte:


18

APL, 39-10-50 = –21

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

Testato su Dyalog con ⎕IO←1e ⎕ML←3ma dovrebbe essere abbastanza portatile.

Spiegazione

                   ?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

Ad ogni passo, questo codice decide se spostare il punto verso sinistra o verso destra a seconda della probabilità che un numero casuale scelto tra (1,5 2,5 ... 27,5 28,5) sia inferiore alla posizione attuale del punto.

Pertanto, quando la posizione attuale del punto (numero di spazi a sinistra) è 1 l'incremento è sempre +1 (tutti quei numeri 1,5 ... 28,5 sono> 1), quando è 29 è sempre -1 (tutti quei numeri sono <29); altrimenti viene scelto casualmente tra +1 e -1, con una probabilità che sia un'interpolazione lineare tra questi estremi. Quindi il punto è sempre in movimento e sempre più probabilmente si sposta verso il centro piuttosto che verso i lati. Se è esattamente nel mezzo, ha una probabilità del 50% di spostarsi su entrambi i lati.

La riduzione (piega a destra) di un valore replicato {...}/a/bè solo un trucco che mi è venuto in mente per ripetere i a-1tempi di una funzione , iniziando con il valore be facendo sì che il risultato di ogni iterazione sia l' argomento accumulatore ( ) al successivo. Il secondo e il successivo argomento di input ( ) e il risultato finale vengono ignorati. Risulta essere molto più breve di una normale chiamata ricorsiva con guardia.

Esempio di esecuzione

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

apl è un'ottima lingua per il golf (difficile da leggere per me); SU!
blabla999,

@ blabla999 APL ha molti simboli comuni e alcuni strani, ma una volta imparata la loro funzione la lingua è facile da leggere e scrivere. Certamente più facile che il rumore ASCII delle lingue da golf, ma mi permetto di dire che è ancora più facile delle lingue normali. La sintassi è molto regolare, hai solo una regola: le espressioni vengono eseguite da destra a sinistra, in modo che possano essere lette da sinistra a destra: +/2×⍳9viene letta "la somma di: due volte: i naturali fino a 9" ma è eseguito in modo opposto.
Tobia,

Sono io o ci sono 31 caratteri per riga qui?
Gusdor,

Ne ottengo 30, sia copiando e incollando una riga dell'esempio sopra riportato in un editor, sia controllando di nuovo il codice. ⎕←30↑...stamperà 30 caratteri più una nuova riga, indipendentemente dalla stringa in cui si trova...
Tobia,

12

Mathematica 138-10-50 = 78

Non sto pubblicando questo perché penso che sia particolarmente ben golfato, ma per altri motivi. Utilizza una definizione del processo Markov con una matrice di transizione progettata per "centrare" la palla.

L'uso di un processo Markov in Mathematica ci consente di calcolare alcune statistiche utili , come vedrai di seguito.

Innanzitutto il codice (spazi non necessari):

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

Alcune uscite:

Mathematica graphics

La matrice di transizione che ho usato è:

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

Mathematica graphics

Ma come ho detto, la parte interessante è che l'uso DiscreteMarkovProcess[]ci consente di ottenere una buona immagine di ciò che sta accadendo.

Vediamo la probabilità che la palla sia 15in qualsiasi momento a t partire da un particolare stato casuale :

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]

Mathematica graphics

Puoi vederlo fluttuare tra 0 e un valore vicino a 0,3, perché a seconda dello stato iniziale puoi raggiungere solo 15 su un numero pari o dispari di passaggi :)

Ora possiamo fare la stessa cosa, ma dicendo a Mathematica di considerare la statistica a partire da tutti i possibili stati iniziali. Qual è la probabilità di essere 15dopo un po ' 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]

Mathematica graphics

Puoi vederlo anche oscillare ... perché? La risposta è semplice: nell'intervallo [1, 29]ci sono numeri più dispari che pari :)

L'oscillazione è quasi scomparsa se chiediamo la probabilità che la palla sia a 14 OR 15:

Mathematica graphics

E potresti anche chiedere il limite (nel senso di Cesaro) delle probabilità dello stato:

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

Mathematica graphics

Oh, beh, forse merito qualche voto negativo per una risposta così fuori tema. Sentiti libero.


2
Questo non è il più breve ma è davvero bello.
Kasra Rahjerdi,

Eseguito l'upgrade e ora il tuo punteggio non è più 2.222 ...
cormullion,

@cormullion Grazie! Puoi annullarlo ridimensionando duramente :)
Dr. belisarius,

7

Bash, punteggio 21 (81 byte - 50 bonus - 10 bonus)

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

In questa risposta, il punto viene "tirato" al centro. Questo può essere testato codificando il punto iniziale su 0 o 30.


Buona soluzione! Ma per favore non codificare il punto di partenza;)
reggaemuffin

1
@Kostronor - oops - L'ho perso e ora l'ho risolto.
Trauma digitale,

2
salva un carattere sostituendolo {1..30}con{P..m}
Geoff Reedy,

Cosa succede se lo oè 1e RANDOM%30ritorna 0? E anche alla prossima iterazione?
user2846289

@VadimR - Penso che le condizioni al contorno siano state corrette ora.
Trauma digitale

5

Rubino 69 66 64-60 = 4

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

Campione:

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

È possibile salvare un byte con i=rand 30;invece di i=rand(30);.
Giordania,

5

Smalltalk, 161 159 145-60 = 85

tutte le colonne sono lunghe 30 caratteri (operando nella stringa mutabile b);

la possibilità di movimento casuale viene regolata polarizzando il valore rnd con p (rnd (0..29) -p), prendendo il segno (-1/0/1) e quindi regolando su (-1 / + 1) tramite (-1 | 1), che viene considerato come delta di movimento (calcola efficacemente: x segno <= 0 ifTrue: -1 ifFalse: 1). Poiché ST utilizza l'indicizzazione basata su 1, devo regolare tutti i riferimenti alle stringhe di +1 (per favore apprezzate l'hack violinoso a -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]

rubando un'idea dalla versione di Ruby (grazie e Up @fipgr), posso liberarmi del controllo 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: (successivamente ho aggiunto manualmente i numeri col e le barre verticali; il codice sopra non li genera)

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

4

C, 86

Supponendo che rand()non sia richiesto il seeding della funzione.

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

Spiegazione:

In C, "%*c"nei *mezzi che la lunghezza dell'uscita avrà una lunghezza minima, e questa lunghezza minima è determinata dall'argomento della chiamata di funzione (in questo caso, è i+=i==30?-1:i==1||rand()%2?1:-1. I cmezzi successivo argomento ( 46) è un carattere ( il punto).

Per quanto riguarda il controllo dei confini, mi scuso di essermi dimenticato. Ora ho aggiunto questo alla risposta, al costo di 15 caratteri. L'operatore ternario funziona come segue: boolean_condition?value_if_true:value_if_false. Si noti che in C true è 1 e false è 0.


Puoi espandere ciò che sta accadendo nel tuo codice? Ho difficoltà a capire come printf("%*c\n",i+=rand()%2?1:-1,46)stampa gli spazi e come impedisce al punto di spostarsi oltre il 29. Grazie in anticipo. (Mi dispiace, non sono un programmatore C.)
Dabbler decente,

@fireeyedboy, spero che tu capisca :)
user12205,

Aaaah, ho avuto la sensazione che stavi tradendo un po 'lì. ;-) Ma il resto è davvero chiaro ora. Grazie! E bella soluzione! C ha anche lo strano comportamento rand()%2in quanto è molto prevedibile (giri dispari / pari)? Ho provato la tua rand()%2con la mia soluzione PHP, ed ha mostrato questo comportamento molto prevedibile (al contrario di rand(0,1). Dato che PHP fa molto uso delle librerie C (se ho ragione), mi chiedevo se il tuo programma C ha lo stesso "difetto" .
Decent Dabbler

@fireeyedboy Non ho eseguito il seeding della rand()funzione. In C se rand()non viene seminato esplicitamente, utilizza sempre lo stesso seme ogni volta. Ecco perché è prevedibile. Se dovessi srand(time());
seminarlo

Ma è così prevedibile che passa da pari a dispari anche su ogni chiamata successiva? PHP reclami rand() non devono più essere seminate srand(), ma mostrano ancora questo strano comportamento.
Dabbler decente,

4

Java: 204 183 182 176 175 caratteri - 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);}}

Innanzitutto, la posizione del punto deve essere 0 < x < 30, ovvero [1-29]. Questo genera un numero compreso tra 0 e 28 uniformemente distribuito e ai fini di questo programma [0-28] ha lo stesso effetto di [1-29]:

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

Personalmente ho preferito se fosse distribuito normalmente intorno alle 14, ma la mia risposta sarebbe stata più lunga:

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

In secondo luogo, questo codice assicura che tende ad essere nel mezzo:

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

La probabilità di ottenere +1 è maggiore in quanto minore è il valore di ie abbiamo l'opposto per -1. Se iè 0, la probabilità di ottenere +1 è del 100% e la probabilità di ottenere -1 è 0%. Se iè 28, accadrà il contrario.

In terzo luogo, sostituendo il 32alla fine con '_'per vedere più facilmente l'output, vediamo che ogni riga ha 30 caratteri più una nuova riga:

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

Grazie a @VadimR (ora, user2846289) per aver sottolineato un malinteso in una versione precedente.

Grazie a @KevinCruijssen per aver rasato 6 caratteri, anche dopo più di due anni e mezzo dopo che questa risposta è stata inizialmente pubblicata.


Ma iarrivare 0è illegale, no?
user2846289

@VadimR, per me iè compreso nell'intervallo [0-29]. Ciò equivale a [1-30] o [288-317], l'output sarebbe lo stesso. Ciò che conta è che ci sono 30 numeri interi nell'intervallo [0-29].
Victor Stafusa,

"Il numero di spazi è la posizione x del punto definito con 0 <x <30" Vale a dire il numero di spazi (o posizione del punto in base 0) è 1..29. inon può essere 0. Capisco che si tratti di divertirsi, ma è ancora triste.
user2846289,

@VadimR, Oh, grazie. Fisso. Ciò significa che il punto non sarà mai nella posizione più giusta, ma comunque è quello che è stato specificato.
Victor Stafusa,

Mi dispiace, ma non ha risolto nulla. Immagina di iottenere 1inizialmente, e alla prima iterazione Math.random()è 0, quindi iottiene 0. Per favore, non fraintendermi, non si tratta della tua risposta. Piuttosto sulla mia incapacità di leggere la maggior parte delle lingue diverse da C-like. Quindi, senza alcuna reazione (fatta eccezione per i voti positivi) sugli errori, come posso sapere se hanno ragione o no?
user2846289

3

Mathematica 157-10-50 = 97

Un numero casuale compreso tra 1 e 30 viene utilizzato per l'avvio. Tutti i rimanenti numeri di colonna dal punto vengono scelti tramite RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, il che si traduce in: "Se il numero di colonna precedente era maggiore di 15, selezionare un numero dall'insieme {-1,1}, con -1 ponderato 2: 1 rispetto a 1; in caso contrario, capovolgere i pesi e scegliere dalla stessa serie.

ReplacePart sostituisce l'elemento in un elenco di 30 spazi vuoti che corrisponde alla colonna di 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

dot


Buon uso diRandomChoice[]
Dr. belisarius,

3

> <>, 358 - 10 = 348

Questo non vincerà su codegolf, ma funziona. (Su Windows 7 con questo interprete , che implementa l'istruzione "p" in modo diverso da come la definisce la pagina 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<

Il nome di questa lingua non può essere cercato su Google , quindi ecco l' articolo esolang per i curiosi.


Puoi codificare il requisito per -50 in meno di 50 caratteri?
Victor Stafusa,

1
@Victor Probabilmente, ma> <> è un dolore gigantesco da codificare (un dolore gigantesco divertente), quindi devo fare una pausa.
SirCxyrtyx,

@SirCxyrtyx questo mi ha fatto ridere. Bene, signore.
Gusdor,

3

PHP, 118 113 112 111 (, -10 punti bonus = 101)

(secondo tentativo, con rand()comportamento orribilmente prevedibile e un po 'più di efficienza)

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

Risultato possibile:

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

PHP, 130 (, -10 punti bonus = 120)

(primo tentativo)

Questo potrebbe probabilmente essere ancora molto più efficiente:

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 sostituisco lo spazio con un carattere di sottolineatura (a fini di visualizzazione), questo è un possibile risultato:

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

Stranamente, se lo sostituisco rand(0,1)con rand()%2(PHP 5.4, su Windows XP), il risultato casuale passa sempre da pari a dispari, e viceversa, a ogni iterazione successiva, rendendo rand()preoccupantemente prevedibile, in tal senso, all'improvviso. Questo "bug" sembra essere noto dal 2004 . Non sono del tutto sicuro che si tratti esattamente dello stesso "bug".


3

J 42 caratteri - 50 -10 = -18

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

Spiegazione, partendo da destra (alcune conoscenze sui treni sono utili):

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

Tendenza al centro, -50, esempio su 1000 corse:

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

Esempio di esecuzione, che genera esattamente 30 byte per riga

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

Un'ottima soluzione!
reggaemuffin,

Un'ottima sfida anche!
jpjacobs,

3

Python 2.7: 126 109-10-50 = 49

Sbarazzarsi del punto di partenza codificato - ora inizia in un punto casuale. Per questo motivo, avevo bisogno di randint, quindi ho deciso di usarlo invece della scelta per l'offset. Per questo ho usato il trucco bool (-1) **.

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)

Alcune grandi risposte qui. Primo tentativo in Python, pensando a miglioramenti. Non aiutato dalla necessità di un'importazione.

-10 - sì 30 caratteri + \ n su ogni riga

-50 - più è lontano dal centro, più è probabile che si sposti dall'altra parte (realizzato costruendo un elenco con un diverso numero di offset + / i)

Tentativo precedente:

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)

Il tuo forciclo può essere tutto su una riga, ma lo è ancora meglio for i in[0]*30:e lo è ancora meglio eval"..."*30.
mbomb007,

2

Java - 198 183 caratteri

Questo è solo un golf semplice, semplice, diretto e poco creativo dell'esempio che hai fornito nella domanda.

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

Lotto - (288 byte - 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.)

Un-giocato a 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.
)

Per generare spazi anziché caratteri di sottolineatura - 372 byte -

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

In cerca di aiuto con la seguente logica, sicuramente questo non è il metodo più efficiente in termini di spazio (! R! Si espanderà 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

Golf fino 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


2

J, 42 personaggi, nessun bonus

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

Esempio di esecuzione:

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

2

Python 2.7 (126 - 10 (lunghezza fissa) - 50 (Tendenza centrale) = 66)

Il seguente programma ha una tendenza centrale rispetto a un campione più ampio

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)

dimostrazione

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

Come s = id (9)% 30 per il seeding. os ha bisogno di essere importato, però? E questo copre l'intera gamma 1-30? Oh aspetta ... * rilegge la disuguaglianza nella parte superiore della pagina *
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)

EDIT: Fix per 50 punti bonus e 10 punti bonus.

EDIT 2: Ancora più breve!


puoi spiegare dove ottieni il bonus di 50 punti? Al momento non lo
capisco

@Kostronor Ho appena visto la modifica per il requisito. Sembra che non ottenga ancora i 50 punti.
aebabis,

@acbabis, ben fatto! È possibile salvare alcuni byte (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 Grazie per i suggerimenti. forTuttavia, non è stato possibile avviare l'array init all'interno del funzionamento; ho dovuto usare un po 'di tempo.
aebabis,

2

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

Golfato :

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

Non golfato :

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

MODIFICA 1 - Non sono del tutto sicuro se il mio codice si qualifica per il bonus di -50 o no.iMancato avvio sempre nel mezzo, ma durante il forciclo, il punto non si muove mai più di come 3 posti entrambe le direzioni, in modo che quando i non iniziare vicino alla metà, il tutto tende a rimanere lì.

MODIFICA 2 - Il codice ora si qualifica per il bonus di -10, poiché stampa un array di 29 caratteri seguito da LF per un totale di esattamente 30 caratteri per riga.


poiché stampa un array di 29 caratteri seguito da LF - Dovrebbero essere 30 caratteri seguiti da un LF.
Victor Stafusa,

@Victor ahh, grazie per la correzione, ho frainteso il post principale.
Tony Ellis,

2

PowerShell, 77-10-50 = 17

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

Produzione

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

Casuale intelligente. È possibile utilizzare una versione golf $x=random 30;1..30|%{' '*($x+=,-1*$x+,1*(29-$x)|random)+'.'|% *ht 30}. 66 byte - 10 - 50 = 6 punti
mazzy

2

R, 107 caratteri - 60 punti bonus = 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è l'indice del punto. aè l'array di 30 spazi. Il punto di partenza è casuale (uniformemente da 1 a 29). Ad ogni iterazione aggiungiamo casualmente -1 o +1 a icon probabilità ponderate: i-1per -1e 29-i per+1 (i valori alimentati come probabilità non devono essere sommati a uno), il che significa che tende ad orientare il punto verso il centro impedendogli dal basso 1 o superiore a 29 (poiché la loro probabilità scende a 0 in entrambi i casi).

Esempio eseguito con _ anziché spazi per la leggibilità:

> 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 non sbaglio a leggere il tuo codice, i può diventare uno 0o 30, no?
user2846289,

Sì, hai ragione, può essere 30 (non di più però), lo cambierò.
plannapus,

1
Ora è riparato. La probabilità di andare da 1 a 0 o di andare da 29 a 30 è ora 0. Il punto di partenza casuale è ora tra 1 e 29.
plannapus,

Suggerimento: è possibile salvare altri 2 caratteri sostituendoli s(1:29,1)con s(29,1).
Sven Hohenstein,

@SvenHohenstein hai ragione, me ne dimentico sempre
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;}}}}

Produzione

spacesostituito con _per leggibilità.

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

Sono abbastanza sicuro che dovrebbe essere possibile ottenere un codice più piccolo if...else if...elsealla fine del codice. Inoltre, il tuo output mi fa dubitare che tende a essere nel mezzo, ma il tuo codice sembra essere giusto.
Victor Stafusa,

Ho dimenticato di aggiornare l'output quando ho modificato il codice. Lo r.Next(30)<p?-1:1;fa accadere. Non sono sicuro di poter andare più piccolo con le ifdichiarazioni. switchè grande a causa dell'obbligatorio break/ returne del finaleelse richiede un default:{}caso e che è anche lungo.
Gusdor,

@Victor grazie per l'input. ho fatto alcune modifiche.
Gusdor,

Se pè zero, p+=r.Next(30)<p?-1:1;otterrà sempre 1, quindi non è necessario per if(p==0). Idem per p==29. pnon sarà mai 30, quindi puoi sbarazzarti di else if.
Victor Stafusa,

@Victor grand. farò quei cambiamenti. Ta.
Gusdor,

1

PHP

Con il bonus di centraggio: 82-50 = 32

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

Per questa versione (versioni precedenti di seguito), rimosso il controllo min / max come indicato nel codice di centraggio. rand(1,28)diventa importante qui in quanto consente di$i++ di spingere se stesso fino a 29 (massimo effettivo).

modifica: parentesi non necessaria, codice spostamento spostato


Algoritmo semplice per la centratura: genera un nuovo numero tra 0 e 29 e lo confronta con quello attuale. Sfrutta la "probabilità" di ottenere un numero sul lato più grande per disegnare verso il centro.

Risultato effettivo: (numerazione delle righe aggiunta successivamente)

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

archiviato:

$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 caratteri

$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 caratteri


Sono un po 'impressionato dal fatto che ho rasato 49 personaggi dalla mia prima versione ...
Yoda,

ho rasato 44 caratteri ora. Il che deve significare che è stata l'ultima volta 39.
Yoda,

1

JavaScript ES6 125 - 10 (30 righe di caratteri) - 50 (passa al centro) = 65

Ho avuto un'epifania mentre salivo l'ascensore per la mia unità, quindi ho dovuto buttarlo giù prima che lasciasse la mia 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 po 'di mescolanza di posizione variabile e un po' di creatività per calcolare la probabilità di spostamento indicata da x/t... (Grazie Kostronor per averlo sottolineato!) Ora ottengo il bonus di -50 per lo spostamento verso il centro e ho anche fatto la posizione di partenza all'interno del gamma completa della linea, che mi ha permesso di radere due byte!

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

Non è che la casualità della posizione iniziale del punto qui è limitata a 2 o 3 possibilità? Ed è ciò che mantiene il punto nel mezzo (a causa del numero molto breve di tiri = 30) e quindi vale -50?
user2846289

Citando il testo del PO : "Il tuo programma inizia con una posizione x casuale e ogni turno sposta questa posizione in modo casuale di 1 a sinistra o a destra" Il mio codice inizialmente viene definito in base al 15+r()*2quale potrebbe essere compreso tra 15 e 16.9999999998 o così che può arrotondare fino a 17. l'aggiunta x+=r()<.5?-1:1genera un po 'più di casualità portandola a un intervallo da 14 a 18, quindi tecnicamente un numero casuale che rientra nella definizione di ciò che è stato chiesto ... Piegando quella regola, capovolgi (+1, -1) nella maggior parte dei casi lo riporterà verso il centro ...;)
WallyWest,

Bene, sulla cosa casuale, mi hai preso ... Voleva essere "una posizione casuale da tutte le posizioni possibili" ma non ti dà molto vantaggio, dato che i 50 punti chiaramente non si applicano! Si prega di rileggere la spiegazione su questo bonus, uno 0,5 percento fisso non lo ottiene!
reggaemuffin,

Punto valido,
rifarò il

Codice @Kostonor aggiornato con soluzione adeguata, punteggio aggiornato di conseguenza!
WallyWest,

1

k, 53-10-50 = -7

Soluzione 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

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

Soluzione 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 byte

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

Sto ancora pensando al bonus di 50 byte.

Spiegazione:

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

Commenti e consigli sono i benvenuti.


Purtroppo, la tua soluzione non è valida, confronta il tuo output con quello di altre soluzioni. Sposta il punto di un carattere.
reggaemuffin,

@Kostronor Oh! Oh! Mi dispiace molto! Ho dimenticato di leggere quella parte della domanda! Proverò presto a sviluppare una nuova versione. Grazie per la segnalazione!
Gaurang Tandon,

Programma @Kostronor modificato.
Gaurang Tandon,

1

JavaScript

114 caratteri - 10 (30 linee di caratteri) - 50 (tira il punto verso il 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('-'))

Tuttavia, ho notato che una ricompensa di 10 caratteri per riempire le righe a 30 caratteri potrebbe essere un cattivo affare; così:

102 caratteri - 50 (tira il punto verso il 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('-'))

Complimenti a @WallyWest per la condizione di pull pull semplificata f()>k/29?1:-1, la mia prima bozza ha usato due condizionali nidificati.


1

Racchetta 227 byte (-10 per 30 caratteri, -50 per passare alla linea mediana = 167)

Ad ogni passo, il punto ha due volte più probabilità di spostarsi verso la linea mediana che lontano da esso:

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

test:

(println "012345678901234567890123456789")
(f)

Produzione:

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

Bella soluzione! La racchetta è davvero interessante. Puoi darti i 50 punti bonus e verificare se
richiedi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.