Le point mobile

16

Votre programme doit imprimer un certain nombre d'espaces, suivis d'un point et d'une nouvelle ligne. Le nombre d'espaces est la position x de votre point définie avec 0 <x <30

Chaque nouvelle ligne est un tour. Votre programme dure 30 tours. Votre programme commence avec une position x aléatoire et chaque tour décale cette position de façon aléatoire de 1 vers la gauche ou la droite, tout en restant dans la zone définie. Chaque tour, votre point doit changer sa position de 1.

Votre score est le nombre de caractères. Vous obtenez 10 points bonus, si chaque ligne imprimée se compose exactement de 30 caractères (et de nouvelle ligne). Vous obtenez 50 points bonus si, tout en étant aléatoire, votre programme a tendance à rester au milieu de la zone définie.

Edit: Les 50 points bonus sont destinés à tirer votre point au milieu. Par exemple, cela s'applique si votre point est à x = 20 et a une chance de 66% d'aller à gauche et de 33% à droite. Cela doit être indépendant du point de départ et ne doit se produire qu'en modifiant dynamiquement la valeur en pourcentage de gauche / droite.

Aucune entrée d'aucune sorte autorisée, la sortie doit se faire sur la console d'exécution!

Pour une meilleure compréhension, voici un exemple lisible en java, qui vous donnerait un score 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
la source
Dans votre exemple, je pense que le int i = (int)(Math.random()*30);devrait être à la int i = 1 + (int)(Math.random()*29);place. En l'état, il génère un nombre 0 >= x > 30au lieu de 0 > x > 30.
Victor Stafusa
Je pense que le code original est correct.
user2846289
c'est correct, car je décale d'abord et l'impression. donc même si la valeur aléatoire dépasse la bordure, elle sera d'abord corrigée puis imprimée.
reggaemuffin
@Kostronor Mais cela implique que la position du point de départ ne suit pas une distribution uniforme, la première position est deux fois plus probable que les autres positions. OTOH, une distribution uniforme n'était pas non plus une exigence.
Victor Stafusa
Il semble qu'il serait plus difficile de créer un programme où le point saute plus. Alors pourquoi y a-t-il un bonus pour restreindre ses déplacements?
Chris Laplante

Réponses:

18

APL, 39 - 10 - 50 = –21

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

Testé sur Dyalog avec ⎕IO←1et ⎕ML←3mais il devrait être assez portable.

Explication

                   ?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

À chaque étape, ce code décide de déplacer le point vers la gauche ou vers la droite en fonction de la probabilité qu'un nombre aléatoire choisi parmi (1,5 2,5 ... 27,5 28,5) soit inférieur à la position actuelle du point.

Par conséquent, lorsque la position actuelle du point (nombre d'espaces à gauche) est 1, l'incrément est toujours +1 (tous ces nombres 1,5 ... 28,5 sont> 1), quand c'est 29, c'est toujours -1 (tous ces nombres sont <29); sinon, il est choisi au hasard entre +1 et -1, avec une probabilité qui est une interpolation linéaire entre ces extrêmes. Ainsi, le point est toujours en mouvement et toujours plus susceptible de se déplacer vers le centre que vers les côtés. S'il est exactement au milieu, il a 50% de chances de se déplacer de chaque côté.

La réduction (à droite) d'une valeur répliquée {...}/a/bn'est qu'une astuce que j'ai trouvée pour répéter une fonction a-1fois, en commençant par la valeur bet en faisant du résultat de chaque itération l' argument accumulator ( ) au suivant. Les deuxième et suivant arguments d'entrée ( ) ainsi que le résultat final sont ignorés. Il s'avère être beaucoup plus court qu'un appel récursif régulier avec garde.

Exemple d'exécution

0/{⎕←30↑'.',⍨⍵↑''⋄⍵+¯1*⍵>.5+?28}/31/?29
                   .          
                    .         
                   .          
                  .           
                 .            
                .             
               .              
                .             
               .              
                .             
               .              
              .               
             .                
              .               
             .                
              .               
               .              
              .               
               .              
                .             
                 .            
                  .           
                 .            
                  .           
                 .            
                  .           
                 .            
                .             
               .              
                .             
Tobia
la source
apl est une excellente langue pour le golf (difficile à lire pour moi, cependant); UP!
blabla999
@ blabla999 APL a de nombreux symboles communs et quelques étranges, mais une fois que vous apprenez leur fonction, la langue est facile à lire et à écrire. Certainement plus facile que le bruit ASCII des langues de «golf», mais j'ose dire que c'est encore plus facile que les langues normales. La syntaxe est très régulière, vous n'avez qu'une seule règle: les expressions sont exécutées de droite à gauche, afin qu'elles puissent être lues de gauche à droite: +/2×⍳9se lit "la somme de: deux fois: les naturels jusqu'à 9" mais est exécuté de la manière opposée.
Tobia
Est-ce moi ou y a-t-il 31 caractères par ligne ici?
Gusdor
J'obtiens 30, à la fois en copiant-collant une ligne de l'exemple ci-dessus dans un éditeur et en vérifiant à nouveau le code. ⎕←30↑...imprimera 30 caractères plus une nouvelle ligne, quelle que soit la chaîne...
Tobia
12

Mathematica 138 - 10 - 50 = 78

Je ne poste pas cela parce que je pense que c'est particulièrement bien joué, mais pour d'autres raisons. Il utilise une définition du processus de Markov avec une matrice de transition conçue pour obtenir la balle «centrée».

L'utilisation d'un processus de Markov dans Mathematica nous permet de calculer des statistiques utiles , comme vous le verrez ci-dessous.

D'abord le code (espaces non nécessaires):

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

Quelques sorties:

Mathematica graphics

La matrice de transition que j'ai utilisée est:

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

Mathematica graphics

Mais comme je l'ai dit, la partie intéressante est que l'utilisation DiscreteMarkovProcess[]nous permet de saisir une bonne image de ce qui se passe.

Voyons la probabilité que la balle soit 15à tout moment à t partir d'un état aléatoire particulier :

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

Vous pouvez voir qu'il oscille entre 0 et une valeur proche de 0,3, car en fonction de l'état de départ, vous ne pouvez atteindre que 15 sur un nombre impair ou pair de pas :)

Maintenant, nous pouvons faire la même chose, mais en disant à Mathematica de considérer la statistique à partir de tous les états initiaux possibles. Quelle est la probabilité d'être 15après un certain temps 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

Vous pouvez voir qu'il oscille aussi ... pourquoi? La réponse est simple: dans l'intervalle [1, 29]il y a plus de nombres impairs que de nombres pairs :)

L'oscillation a presque disparu si nous demandons la probabilité que la balle soit à 14 OR 15:

Mathematica graphics

Et vous pourriez aussi demander la limite (au sens Cesaro) des probabilités d'état:

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

Mathematica graphics

Oh, eh bien, peut-être que je mérite des downvotes pour une telle réponse hors sujet. N'hésitez pas.

Dr. belisarius
la source
2
Ce n'est pas le plus court mais c'est vraiment cool.
Kasra Rahjerdi
Surévalué, et votre score n'est désormais plus de 2,222 ...
cormullion
@cormullion Merci! Vous pouvez annuler cela en votant fort :)
Dr. belisarius
7

Bash, marque 21 (81 octets - 50 bonus - 10 bonus)

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

Dans cette réponse, le point est "tiré" vers le milieu. Cela peut être testé en codant en dur le point de départ à 0 ou 30.

Traumatisme numérique
la source
Bonne solution! Mais veuillez ne pas coder en dur le point de départ;)
reggaemuffin
1
@Kostronor - oups - j'ai raté cela, et je l'ai maintenant corrigé.
Digital Trauma
2
sauver un personnage en le remplaçant {1..30}par{P..m}
Geoff Reedy
Et si oest 1et RANDOM%30revient 0? Et à la prochaine itération aussi?
user2846289
@VadimR - Je pense que les conditions aux limites sont maintenant fixées.
Digital Trauma
5

Rubis 69 66 64-60 = 4

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

Échantillon:

            .             
           .              
            .             
           .              
          .               
           .              
            .             
             .            
              .           
             .            
              .           
               .          
              .           
               .          
              .           
             .            
            .             
             .            
              .           
             .            
              .           
             .            
            .             
             .            
            .             
             .            
            .             
           .              
          .               
           .              
fgp
la source
Vous pouvez enregistrer un octet avec i=rand 30;au lieu de i=rand(30);.
Jordan
5

Smalltalk, 161 159 145-60 = 85

toutes les colonnes ont une longueur de 30 caractères (fonctionnant dans la chaîne mutable b);

la chance de mouvement aléatoire est ajustée en biaisant la valeur rnd avec p (rnd (0..29) -p), en prenant le signe (-1/0/1) puis en ajustant à (-1 / + 1) via (-1 | 1), qui est considéré comme un delta de déplacement (calcule effectivement: signe x <= 0 ifTrue: -1 ifFalse: 1). Comme ST utilise une indexation basée sur 1, je dois ajuster toutes les références de chaîne de +1 (plz apprécie le hack de violon -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]

voler une idée de la version Ruby (thanx & Up @fipgr), je peux me débarrasser du contrôle 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]

sortie: (J'ai ajouté manuellement les numéros de col et les barres verticales par la suite; le code ci-dessus ne les génère pas)

 012345678901234567890123456789
|                     .        |
|                    .         |
|                   .          |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|                 .            |
|                .             |
|               .              |
|                .             |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                  .           |
|                 .            |
|                .             |
|               .              |
|                .             |
|               .              |
|                .             |
|               .              |
|              .               |
|               .              |
|              .               |
 012345678901234567890123456789
blabla999
la source
4

C, 86

En supposant que l'amorçage de la rand()fonction n'est pas requis.

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

Explication:

En C, dans "%*c"le *sens où la longueur de la sortie aura une longueur minimale, et cette longueur minimale est déterminée par l'argument de l'appel de fonction (dans ce cas, elle l'est i+=i==30?-1:i==1||rand()%2?1:-1. La csignifie que l'argument suivant ( 46) est un caractère ( le point).

En ce qui concerne la vérification des limites, je m'excuse d'avoir oublié cela. J'ai maintenant ajouté ceci à la réponse, au prix de 15 caractères. L'opérateur ternaire fonctionne comme suit: boolean_condition?value_if_true:value_if_false. Notez qu'en C, true est 1 et false est 0.

user12205
la source
Pouvez-vous développer ce qui se passe dans votre code? J'ai du mal à comprendre comment printf("%*c\n",i+=rand()%2?1:-1,46)imprime les espaces, ainsi que comment il empêche le point de se déplacer au-delà de 29. Merci à l'avance. (Désolé, je ne suis pas un programmeur C.)
Decent Dabbler
@fireeyedboy fait, j'espère que vous comprenez :)
user12205
Aaaah, j'avais en quelque sorte l'impression que tu trichais un peu là-bas. ;-) Mais le reste est clair maintenant. Je vous remercie! Et belle solution! C a-t-il également le comportement étrange rand()%2en ce sens qu'il est très prévisible (tours impairs / pairs)? J'ai essayé votre rand()%2dans ma solution PHP, et elle présentait ce comportement très prévisible (par opposition à rand(0,1). Étant donné que PHP utilise beaucoup les bibliothèques C (si je me trompe), je me demandais si votre programme C avait le même «défaut» .
Dabbler décent
@fireeyedboy Je n'ai pas créé la rand()fonction. En C, si elle rand()n'est pas définie explicitement, elle utilise toujours la même valeur initiale à chaque fois. C'est pourquoi c'est prévisible. Si je devais le semer, je peux le faire, srand(time());ce qui coûte 14 caractères
user12205
Mais est-il si prévisible qu'il passe également de impair à pair à chaque appel ultérieur? Les revendications PHP rand()n'ont plus besoin d'être srand()complétées, mais montrent toujours ce comportement étrange .
Decent Dabbler
4

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

Tout d'abord, la position du point doit être 0 < x < 30, c'est-à-dire [1-29]. Cela génère un nombre compris entre 0 et 28 uniformément distribué, et pour les besoins de ce programme, [0-28] a le même effet que [1-29]:

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

Personnellement, j'ai préféré qu'il soit normalement distribué vers 14 heures, mais ma réponse serait plus longue:

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

Deuxièmement, ce code garantit qu'il a tendance à être au milieu:

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

La probabilité d'obtenir +1 est plus grande car plus petite est la valeur de i, et nous avons l'inverse pour -1. Si iest 0, la probabilité d'obtenir +1 est de 100% et la probabilité d'obtenir -1 est de 0%. Si ic'est 28, le contraire se produira.

Troisièmement, en remplaçant le 32à la fin par '_'pour voir la sortie plus facilement, nous voyons que chaque ligne a 30 caractères plus une nouvelle ligne:

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

Merci à @VadimR (maintenant, user2846289) d'avoir signalé un malentendu dans une version précédente.

Merci à @KevinCruijssen d'avoir rasé 6 caractères, même après plus de deux ans et demi après la publication initiale de cette réponse.

Victor Stafusa
la source
Mais y ialler 0est illégal, non?
user2846289
@VadimR, pour moi iest dans la plage [0-29]. C'est équivalent à [1-30] ou [288-317], la sortie serait la même. Ce qui importe, c'est qu'il y a 30 nombres entiers dans l'intervalle [0-29].
Victor Stafusa
"Le nombre d'espaces est la position x de votre point définie avec 0 <x <30" C'est-à- dire que le nombre d'espaces (ou position de point basée sur 0) est 1..29. ine peut pas être 0. Je comprends qu'il s'agit de s'amuser mais c'est quand même triste.
user2846289
@VadimR, Oh, merci. Fixé. Cela signifie que le point ne sera jamais dans la position la plus à droite, mais de toute façon, c'est ce qui a été spécifié.
Victor Stafusa
Je suis désolé, mais cela n'a rien arrangé. Imaginez iobtient un 1premier temps , et à la première itération Math.random()est 0, puis iobtient 0. S'il vous plaît, ne vous méprenez pas, ce n'est pas votre réponse. Plutôt de mon incapacité à lire la plupart des langues autres que le C-like. Puis, sans réaction (sauf pour les votes positifs) sur les erreurs, comment puis-je savoir qu'elles ont raison ou non?
user2846289
3

Mathematica 157-10-50 = 97

Un nombre aléatoire de 1 à 30 est utilisé pour commencer. Tous les numéros de colonne restants du point sont choisis via RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, ce qui se traduit par: "Si le numéro de colonne précédent était supérieur à 15, sélectionnez un numéro dans l'ensemble {-1,1}, avec -1 pondéré 2: 1 par rapport à 1; sinon, retournez les poids et choisissez dans le même ensemble.

ReplacePart remplace l'élément dans une liste de 30 espaces vides qui correspond à la colonne d'intérêt.

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

DavidC
la source
RandomChoice[]
Bonne
3

> <>, 358 - 10 = 348

Cela ne gagnera pas chez codegolf, mais ça marche. (Sous Windows 7 avec cet interpréteur , qui implémente l'instruction "p" différemment de la définition de la page 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<

Le nom de cette langue ne peut pas être googlé, alors voici son article esolang pour les curieux.

SirCxyrtyx
la source
Pouvez-vous coder l'exigence pour le -50 en moins de 50 caractères?
Victor Stafusa
1
@Victor Probablement, mais> <> est une douleur géante à coder (une douleur géante amusante), donc je dois faire une pause.
SirCxyrtyx
@SirCxyrtyx cela m'a fait rire. Bien joué monsieur.
Gusdor
3

PHP, 118 113 112 111 (, 10 points de bonus = 101)

(deuxième essai, avec un rand()comportement horriblement prévisible et un peu plus d'efficacité)

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

Résultat possible:

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

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

(premier essai)

Cela pourrait probablement être encore plus efficace:

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 je remplace l'espace par un trait de soulignement (à des fins d'affichage), ceci est un résultat possible:

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

Curieusement, si je remplace rand(0,1)par rand()%2(PHP 5.4, sous Windows XP), le résultat aléatoire passe toujours de impair à pair, et vice versa, à chaque prochaine itération, ce qui rend tout à coup rand()prévisible, dans ce sens, tout à coup. Ce «bug» semble être connu depuis 2004 . Je ne sais pas vraiment si c'est exactement le même «bug».

Dabbler décent
la source
3

J 42 caractères - 50-10 = -18

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

Explication, en partant de la droite (certaines connaissances sur les trains sont utiles):

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

Tendance centrale, -50, exemple sur 1000 pistes:

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

Exemple exécuté, produisant exactement 30 octets par ligne

_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________
_____________.________________
____________._________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________
jpjacobs
la source
Une très bonne solution!
reggaemuffin
Un très bon défi aussi!
jpjacobs
3

Python 2.7: 126 109 -10-50 = 49

Débarrassé du point de départ codé en dur - commence maintenant au point aléatoire. Pour cette raison, j'avais besoin de Randint, j'ai donc décidé de l'utiliser au lieu de choisir pour le décalage. J'ai utilisé le truc (-1) ** bool pour cela.

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)

Quelques bonnes réponses ici. Première tentative en Python, en pensant à des améliorations. Pas aidé par la nécessité d'une importation.

-10 - oui 30 caractères + \ n sur chaque ligne

-50 - plus on s'éloigne du centre, plus il y a de chances que l'on bouge dans l'autre sens (accompli en construisant une liste avec un nombre différent de décalages + / i)

Tentative précédente:

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
la source
Votre forboucle peut être sur une seule ligne, mais c'est encore mieux for i in[0]*30:et c'est encore mieux eval"..."*30.
mbomb007
2

Java - 198 183 caractères

C'est juste un golf simple, simple, direct et non créatif de l'exemple que vous avez donné dans la question.

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
la source
2

Lot - (288 octets - 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.)

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

Pour afficher des espaces au lieu de traits de soulignement - 372 octets -

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

Vous cherchez de l'aide avec la logique suivante, ce n'est sûrement pas la méthode la plus économe en espace (! R! Passera à 1 ou 2) -

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

Il joue sur: 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

dégrader
la source
2

J, 42 caractères, pas de bonus

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

Exemple d'exécution:

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

Python 2.7 (126-10 (longueur fixe) - 50 (tendance centrale) = 66)

Les programmes suivants ont une tendance centrale par rapport à un échantillon plus large

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)

Démo

         .           
        .            
       .             
      .              
     .               
      .              
       .             
        .            
         .           
          .          
           .         
          .          
           .         
          .          
         .           
        .            
       .             
        .            
       .             
      .              
     .               
      .              
       .             
      .              
     .               
    .                
   .                 
    .                
   .                 
    .              
Abhijit
la source
Comme le s = id (9)% 30 pour l'ensemencement. os a besoin d'importer, cependant? Et cela couvre-t-il la gamme complète 1-30? Oh attendez ... * relit l'inégalité en haut de page *
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: correction du bonus de 50 points et du bonus de 10 points.

EDIT 2: Encore plus court!

aebabis
la source
pouvez-vous expliquer où vous obtenez le bonus de 50 points? Je ne
comprends
@Kostronor Je viens de voir la modification de l'exigence. On dirait que je n'obtiens pas encore les 50 points.
aebabis
@acbabis, bravo! Vous pouvez enregistrer quelques octets (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 Merci pour les conseils. forCependant, n'a pas pu obtenir l'init du tableau dans le travail; a dû utiliser un do pendant un certain temps.
aebabis
2

RÉ - 167, 162, 144 (154 - 10)

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

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

EDIT 1 - Je ne sais pas trop si mon code est admissible au bonus -50 ou non. ine pas toujours commencer au milieu, mais au cours de la forboucle, le point ne se déplace plus comme 3 endroits ou l' autre direction, alors quand i ne commence près du milieu, la chose a tendance à rester là - bas aussi.

EDIT 2 - Le code se qualifie désormais pour le bonus -10, car il imprime un tableau de 29 caractères suivi de LF pour un total d'exactement 30 caractères par ligne.

Tony Ellis
la source
car il imprime un tableau de 29 caractères suivi de LF - Il devrait être de 30 caractères suivis d'un LF.
Victor Stafusa
@Victor ahh, merci pour la correction, j'ai mal interprété le message principal.
Tony Ellis
2

PowerShell, 77 - 10 - 50 = 17

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

Production

_.____________________________
__.___________________________
___.__________________________
____._________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
______._______________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
___________.__________________
__________.___________________
___________.__________________
____________._________________
___________.__________________
__________.___________________
_________.____________________
__________.___________________
_________.____________________
________._____________________
_________.____________________
________._____________________
_________.____________________
__________.___________________
Rynant
la source
Aléatoire intelligent. Vous pourriez utiliser une version golfée $x=random 30;1..30|%{' '*($x+=,-1*$x+,1*(29-$x)|random)+'.'|% *ht 30}. 66 octets - 10 - 50 = 6 points de score
mazzy
2

R, 107 caractères - 60 points 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='')}

iest l'indice du point. aest le tableau de 30 espaces. Le point de départ est aléatoire (uniformément de 1 à 29). À chaque itération, nous ajoutons aléatoirement -1 ou +1 à iavec des probabilités pondérées:i-1 pour -1et 29-i pour +1(les valeurs alimentées en probabilités n'ont pas besoin de résumer à un), ce qui signifie qu'il a tendance à orienter le point vers le centre tout en l'empêchant d'en dessous 1 ou supérieur à 29 (puisque leur probabilité tombe à 0 dans les deux cas).

Exemple exécuté avec _au lieu d'espaces pour la lisibilité:

> 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
la source
Si je ne me trompe pas en lisant votre code, i peut devenir soit 0ou 30, non?
user2846289
Oui, vous avez raison, cela peut être 30 (pas plus cependant), je vais changer cela.
plannapus
1
C'est réparé maintenant. La probabilité de passer de 1 à 0 ou de 29 à 30 est désormais de 0. Le point de départ aléatoire est désormais compris entre 1 et 29.
plannapus
Astuce: vous pouvez enregistrer 2 caractères supplémentaires en les remplaçant s(1:29,1)par s(29,1).
Sven Hohenstein
@SvenHohenstein vous avez raison j'oublie toujours celle-là
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;}}}}

Production

spaceremplacé par _pour plus de lisibilité.

____________.________________
___________._________________
__________.__________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_______________._____________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
_____________._______________
______________.______________
_____________._______________
____________.________________
___________._________________
____________.________________
___________._________________
____________.________________
___________._________________
__________.__________________
___________._________________
Gusdor
la source
Je suis à peu près sûr qu'il devrait être possible d'obtenir un code plus petit if...else if...elseà la fin de votre code. De plus, votre sortie me fait douter qu'il a tendance à être au milieu, mais votre code semble être correct.
Victor Stafusa
J'ai oublié de mettre à jour la sortie lorsque j'ai modifié le code. Le r.Next(30)<p?-1:1;rend cela possible. Je ne suis pas sûr que vous puissiez aller plus petit avec les ifdéclarations. switchest grand à cause du obligatoire break/ returnet la finale elsenécessite un default:{}étui et c'est aussi long.
Gusdor
@Victor merci pour l'entrée. j'ai fait quelques modifications.
Gusdor
Si pest nul, le p+=r.Next(30)<p?-1:1;aura toujours 1, donc pas besoin de if(p==0). Idem pour p==29. pne sera jamais 30, vous pouvez donc vous débarrasser de la else if.
Victor Stafusa
@Victor grand. mal faire ces changements. Ta.
Gusdor
1

PHP

Avec le bonus de centrage: 82 - 50 = 32

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

Pour cette version (anciennes versions ci-dessous), suppression de la vérification min / max comme cela est pris en charge dans le code de centrage. rand(1,28)devient important ici car il permet $i++au Pousser jusqu'à 29 (max réel).

modifier: parenthèses inutiles, code de décalage déplacé


Algorithme simple de centrage: génère un nouveau nombre compris entre 0 et 29 et le compare à l'actuel. Profite de la "probabilité" d'obtenir un nombre plus grand pour se rapprocher du centre.

Résultat réel: (numérotation des lignes ajoutée par la suite)

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

Archivé:

$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 caractères

$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 caractères

Yoda
la source
Je suis un peu impressionné d'avoir rasé 49 caractères depuis ma première version ...
Yoda
rasé 44 caractères maintenant. Ce qui doit signifier que c'était la dernière fois.
Yoda
1

JavaScript ES6 125 - 10 (30 lignes de caractères) - 50 (se déplace vers le milieu) = 65

J'ai eu une révélation en montant l'ascenseur jusqu'à mon unité, j'ai donc dû le descendre avant qu'il ne quitte ma mémoire ...

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 petit changement de position variable et un peu de créativité pour calculer la probabilité de changement indiquée par x/t... gamme complète de la ligne, ce qui m'a permis de raser deux octets!

....5....0....5....0....5....0 <-- Ruler
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
__.___________________________
_.____________________________
__.___________________________
___.__________________________
__.___________________________
___.__________________________
____._________________________
_____.________________________
______._______________________
_______.______________________
________._____________________
_______.______________________
______._______________________
_______.______________________
________._____________________
_______.______________________
________._____________________
_________.____________________
__________.___________________
_________.____________________
__________.___________________
___________.__________________
____________._________________
_____________.________________
______________._______________
WallyWest
la source
N'est-ce pas que le caractère aléatoire de la position initiale des points ici est limité à 2 ou 3 possibilités? Et c'est ce qui maintient le point au milieu (en raison du nombre très court de pistes = 30) et vaut donc -50?
user2846289
Citant le texte de l' OP : "Votre programme commence avec une position x aléatoire et à chaque tour décale cette position de manière aléatoire de 1 vers la gauche ou la droite" Mon code est initialement défini, 15+r()*2ce qui pourrait être n'importe quoi de 15 à 16.9999999998 ou ainsi qui pourrait arrondir off to 17. l'addition x+=r()<.5?-1:1jette un peu plus de hasard en le portant à une plage de 14 à 18, donc techniquement un nombre aléatoire qui est dans la définition de ce qui a été demandé ... En pliant cette règle, le flip (+1, -1) le ramènera dans la plupart des cas vers le milieu ...;)
WallyWest
Eh bien, sur la chose aléatoire, vous m'avez eu ... C'était censé être 'une position aléatoire de toutes les positions possibles' mais cela ne vous donne pas beaucoup d'avantages, car les 50 points ne s'appliquent clairement pas! Veuillez relire l'explication de ce bonus, un pourcentage fixe de 0,5% ne l'obtient pas!
reggaemuffin
Point valable, je vais refaire mon score en conséquence ...
WallyWest
@Kostonor Code mis à jour avec une solution appropriée, score mis à jour en conséquence!
WallyWest
1

k, 53 - 10 - 50 = -7

Solution 1

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

Usage

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

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

Solution 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
la source
1

Scala, 95-10 = 85 octets

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

Je pense toujours au bonus de 50 octets.

Explication:

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

Vos commentaires et conseils sont les bienvenus.

Gaurang Tandon
la source
Malheureusement, votre solution n'est pas admissible, comparez votre sortie avec la sortie d'autres solutions. Décale le point d'un caractère.
reggaemuffin
@Kostronor Oh! Oh! Je suis vraiment désolé! J'ai oublié de lire cette partie de la question! J'essaierai de développer une nouvelle version prochainement. Merci d'avoir souligné!
Gaurang Tandon
Programme @Kostronor édité.
Gaurang Tandon
1

Javascript

114 caractères - 10 (30 lignes de caractères) - 50 (tirez le point vers le milieu) = 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('-'))

Cependant, j'ai remarqué qu'une récompense de 10 caractères pour avoir rempli les lignes jusqu'à 30 caractères peut être une mauvaise affaire; donc:

102 caractères - 50 (tirez le point vers le milieu) = 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('-'))

Félicitations à @WallyWest pour la direction de traction simplifiée conditionnelle f()>k/29?1:-1, mon premier projet a utilisé deux conditions imbriquées.

codeporn
la source
1

Raquette 227 octets (-10 pour 30 caractères, -50 pour passer à la ligne médiane = 167)

À chaque étape, le point est deux fois plus susceptible de se déplacer vers la ligne médiane que de s'éloigner de lui:

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

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

Essai:

(println "012345678901234567890123456789")
(f)

Production:

"012345678901234567890123456789"
                       *       
                      *        
                       *       
                        *      
                         *     
                        *      
                       *       
                      *        
                     *         
                      *        
                     *         
                    *          
                     *         
                      *        
                     *         
                    *          
                   *           
                  *            
                 *             
                *              
               *               
                *              
                 *             
                *              
                 *             
                *              
                 *             
                *              
                 *             
                *              
               *               
rnso
la source
Bonne solution! La raquette est vraiment intéressante. Vous pouvez vous donner les 50 points bonus et vérifier si vous postulez pour les 10 supplémentaires :-)
reggaemuffin