Смещающая точка


16

Ваша программа должна распечатать несколько пробелов, за которыми следуют точка и символ новой строки. Количество пробелов - это позиция x вашей точки, определенная с 0 <x <30

Каждая новая линия - это поворот. Ваша программа работает за 30 ходов. Ваша программа начинается со случайной позиции x и каждый ход меняет эту позицию случайным образом на 1 влево или вправо, оставаясь в пределах определенной области. Каждый ход ваша точка должна менять свою позицию на 1.

Ваша оценка - это количество символов. Вы получаете 10 бонусных баллов, если каждая напечатанная строка состоит ровно из 30 символов (и новой строки). Вы получаете 50 бонусных баллов, если в случайном порядке ваша программа имеет тенденцию оставаться в середине определенной области.

Изменить: 50 бонусных очков предназначены, чтобы вытащить вашу точку к середине. Например, это применимо, если ваша точка находится в точке х = 20 и имеет шанс 66% идти влево и 33% идти вправо. Это должно быть независимо от начальной точки и должно происходить только путем динамического изменения процентного значения влево / вправо.

Никакой ввод не разрешен, вывод должен быть на исполняющей консоли!

Для лучшего понимания, вот читаемый пример в Java, который даст вам 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('.');
    }
}

В вашем примере, я думаю, что int i = (int)(Math.random()*30);должно быть int i = 1 + (int)(Math.random()*29);вместо. Как есть, он генерирует число 0 >= x > 30вместо 0 > x > 30.
Виктор Стафуса

Я думаю, что оригинальный код правильный.
user2846289

это правильно, потому что я смещаюсь первым и печатью. так что даже если случайное значение превышает границу, if сначала исправит, а затем напечатает.
reggaemuffin

@Kostronor Но это подразумевает, что позиция начальной точки не следует равномерному распределению, первая позиция в два раза больше, чем другие позиции. OTOH, будучи равномерно распределенным, также не было требованием.
Виктор Стафуса

Похоже, было бы сложнее создать программу, в которой точка больше прыгает. Так почему же существует бонус за ограничение его движения?
Крис Лапланте

Ответы:


18

APL, 39 - 10 - 50 = –21

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

Проверено на Dyalog с ⎕IO←1и, ⎕ML←3но оно должно быть довольно портативным.

объяснение

                   ?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

На каждом этапе этот код решает, перемещать ли точку влево или вправо, в зависимости от вероятности того, что выбранное случайное число (1,5 2,5 ... 27,5 28,5) меньше текущей позиции точки.

Поэтому, когда текущая позиция точки (количество пробелов слева) равна 1, приращение всегда равно +1 (все эти числа 1,5 ... 28,5> 1), когда это 29, это всегда -1 (все эти числа <29); в противном случае он выбирается случайным образом между +1 и -1, с вероятностью, что это линейная интерполяция между этими крайностями. Таким образом, точка всегда движется и всегда с большей вероятностью движется к центру, чем к сторонам. Если он точно посередине, у него есть 50% шанс переместиться в любую сторону.

Сокращение (правое сгибание) реплицируемого значения {...}/a/b- это просто прием, который я придумал, чтобы повторить функцию a-1раз, начиная со значения bи имея результат каждой итерации в качестве аргумента аккумулятора ( ) для следующего. Второй и следующий входные аргументы ( ), а также конечный результат игнорируются. Оказывается, это намного короче, чем обычный рекурсивный вызов с охраной.

Пример запуска

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

apl - отличный язык для гольфа (хотя мне трудно его читать); UP!
blabla999

@ blabla999 APL имеет много общих символов и некоторые странные, но как только вы изучите их функции, язык будет легко читать и писать. Конечно, легче, чем ASCII шум «языков для гольфа», но я бы рискнул сказать, что это даже проще, чем обычные языки. Синтаксис очень регулярный, у вас есть только одно правило: выражения выполняются справа налево, так что их можно читать слева направо: +/2×⍳9читается как «сумма: два раза: натуральное число до 9», но выполнено в обратном порядке.
Tobia

Это я или здесь 31 строка в строке?
Gusdor

Я получаю 30, как путем копирования строки из примера, приведенного выше, в редактор, так и путем повторной проверки кода. ⎕←30↑...напечатает 30 символов плюс символ новой строки, независимо от того, в какой строке находится...
Tobia

12

Mathematica 138 - 10 - 50 = 78

Я не публикую это, потому что думаю, что это особенно хорошо, но по другим причинам. Он использует определение Марковского процесса с матрицей перехода, предназначенной для центрирования шара.

Использование марковского процесса в Mathematica позволяет нам вычислить некоторые полезные статистические данные , как вы увидите ниже.

Сначала код (пробелы не нужны):

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

Некоторые выводы:

Математическая графика

Матрица перехода, которую я использовал:

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

Математическая графика

Но, как я уже сказал, интересная часть заключается в том, что использование DiscreteMarkovProcess[]позволяет нам получить хорошее представление о том, что происходит.

Давайте посмотрим на вероятность того, что мяч будет 15в любое время, t начиная с определенного случайного состояния :

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]

Математическая графика

Вы можете видеть, что он колеблется между 0 и значением около 0,3, потому что в зависимости от начального состояния вы можете достичь только 15 с нечетным или четным числом шагов :)

Теперь мы можем сделать то же самое, но сказать Mathematica рассмотреть статистику, начиная со всех возможных начальных состояний. Какова вероятность быть 15через какое-то время 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]

Математическая графика

Вы можете видеть, что это также колеблется ... почему? Ответ прост: в интервале [1, 29]больше нечетных, чем четных чисел :)

Колебания почти исчезнут, если мы спросим вероятность того, что мяч находится в 14 OR 15:

Математическая графика

И вы могли бы также попросить предел (в смысле Чезаро) вероятности состояния:

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

Математическая графика

О, ну, возможно, я заслуживаю некоторых отрицательных ответов за такой не по теме ответ. Не стесняйтесь.


2
Это не самое короткое, но это действительно круто.
Касра Рахьерди

Проголосовал, и теперь ваш счет больше не 2222 ...
cormullion

@cormullion Спасибо! Вы можете отменить это, сильно понизив :)
Dr. belisarius

7

Bash, оценка 21 (81 байт - 50 бонусов - 10 бонусов)

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

В этом ответе точка «вытягивается» назад к середине. Это можно проверить путем жесткого кодирования начальной точки в 0 или 30.


Хорошее решение! Но, пожалуйста, не указывайте начальную точку жестко;)
reggaemuffin

1
@Kostronor - упс - я пропустил это, и теперь исправил это.
Цифровая травма

2
сохранить символ, заменив {1..30}на{P..m}
Джефф Риди

Что, если oесть 1и RANDOM%30возвращается 0? И на следующей итерации тоже?
user2846289

@VadimR - Я думаю, что граничные условия сейчас зафиксированы.
Цифровая травма

5

Рубин 69 66 64-60 = 4

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

Образец:

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

Вы можете сохранить байт i=rand 30;вместо i=rand(30);.
Джордан,

5

Smalltalk, 161 159 145-60 = 85

все столбцы имеют длину 30 символов (работает в изменяемой строке b);

шанс случайного движения корректируется путем смещения rnd-значения с помощью p (rnd (0..29) -p), взятия знака (-1/0/1) и последующей корректировки на (-1 / + 1) с помощью (-1 | 1), которая принимается как дельта хода (эффективно вычисляет: x sign <= 0 ifTrue: -1 ifFalse: 1). Так как ST использует индексирование на основе 1, я должен скорректировать все строковые ссылки на +1 (пожалуйста, оцените взлом -1 | 1 бита ;-)).

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]

украдя идею из версии Ruby (thanx & Up @fipgr), я могу избавиться от проверки 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]

Вывод: (я вручную добавил номера столбцов и вертикальные столбцы; код выше не генерирует их)

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

4

С 86

Предполагая, что посев rand() функция заполнения не требуется.

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

Объяснение:

В C "%*c"это *означает, что длина вывода будет иметь минимальную длину, и эта минимальная длина определяется аргументом вызова функции (в данном случае этоi+=i==30?-1:i==1||rand()%2?1:-1 . cОзначает следующий аргумент (46 ) представляет собой символ ( точка).

Что касается пограничного контроля, я прошу прощения, что я забыл об этом. Теперь я добавил это к ответу, стоимостью 15 символов. Тройной оператор работает следующим образом : boolean_condition?value_if_true:value_if_false. Обратите внимание, что в C true равно 1, а false равно 0.


Можете ли вы рассказать о том, что происходит в вашем коде? У меня возникают проблемы с пониманием того, как printf("%*c\n",i+=rand()%2?1:-1,46)печатать пробелы, а также как это удерживает точку от возможного продвижения мимо 29. Заранее спасибо. (Извините, я не программист на Си.)
Достойный Дабблер

@fireeyedboy сделано, надеюсь, вы понимаете :)
user12205

А-а-а-а, у меня вроде было ощущение, что ты немного обманывал. ;-) Но остальное действительно ясно сейчас. Спасибо! И хорошее решение! Есть ли у C странное поведение с rand()%2тем, что оно очень предсказуемо (нечетные / четные повороты)? Я попробовал ваше rand()%2в своем решении PHP, и оно показало это очень предсказуемое поведение (в отличие от rand(0,1). Поскольку PHP много использует библиотеки C (если я прав), мне было интересно, имеет ли ваша программа C тот же «недостаток» .
Достойный Dabbler

@fireeyedboy Я не запускал эту rand()функцию. В C, если rand()явно не выделен, он всегда использует одно и то же начальное число каждый раз. Вот почему это предсказуемо. Если бы мне пришлось посеять это, я могу сделать, srand(time());что стоит 14 символов
user12205

Но настолько ли это предсказуемо, что переключается с нечетного на четное при каждом последующем вызове? PHP претензии rand() не нужно засевают srand()больше, но все же показывает , что это странное поведение.
Приличный Дабблер

4

Java: 204 183 182 176 175 символов - 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);}}

Во-первых, позиция точки должна быть 0 < x < 30, то есть [1-29]. Это генерирует число от 0 до 28, равномерно распределенное, и для целей этой программы [0-28] имеет тот же эффект, что и [1-29]:

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

Я лично предпочел бы, чтобы это было нормально распределено около 14, но мой ответ был бы длиннее:

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

Во-вторых, этот код гарантирует, что он будет посередине:

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

Вероятность получить +1 тем больше, чем меньше значение i, а у нас есть обратное для -1. Если i0, вероятность получения +1 составляет 100%, а вероятность получения -1 составляет 0%. Если iэто 28, произойдет обратное.

В-третьих, заменив 32в конце на, '_'чтобы легче видеть вывод, мы видим, что каждая строка имеет 30 символов плюс новую строку:

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

Спасибо @VadimR (теперь user2846289) за то, что он указал на недоразумение в предыдущей версии.

Спасибо @KevinCruijssen за 6 символов, даже спустя более двух с половиной лет после того, как этот ответ был первоначально опубликован.


Но iдобраться до 0незаконна, не так ли?
user2846289

@VadimR, для меня iв диапазоне [0-29]. Это эквивалентно [1-30] или [288-317], результат будет таким же. Важно то, что в интервале есть 30 целых чисел [0-29].
Виктор Стафуса

«Количество пробелов - это позиция x вашей точки, определенная с 0 <x <30» Т.е. количество пробелов (или позиция точки на основе 0) составляет 1..29. iне может быть 0. Я понимаю, что это все о веселье, но все же это грустно.
user2846289

@VadimR, О, спасибо. Исправлена. Это означает, что точка никогда не будет в самом правильном положении, но в любом случае, это то, что было указано.
Виктор Стафуса

Извините, но это ничего не исправило. Представьте себе , iполучает на 1начальном этапе, и на первой итерации Math.random()это 0, то iполучает 0. Пожалуйста, не поймите меня неправильно, дело не в вашем ответе. Скорее о моей неспособности читать большинство языков, кроме C-like. Тогда без всякой реакции (за исключением возражений) на ошибки, откуда мне знать, правы они или нет?
user2846289

3

Mathematica 157-10-50 = 97

Для запуска используется случайное число от 1 до 30. Все остальные номера столбцов из точки выбираются через RandomChoice[If[c > 15, {2, 1}, {1, 2}] -> {-1, 1}] + c, что означает: «Если предыдущий номер столбца был больше 15, выберите одно число из набора {-1,1} с -1, взвешенным 2: 1 по отношению к 1, в противном случае переверните веса и выберите один и тот же набор.

ReplacePart заменяет элемент в списке из 30 пробелов, который соответствует интересующему столбцу.

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

точка


Хорошее использованиеRandomChoice[]
доктор Belisarius

3

> <>, 358 - 10 = 348

Это не победит в Codegolf, но это работает. (В Windows 7 с этим интерпретатором , который реализует инструкцию «p» иначе, чем это определяет страница 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<

Название этого языка не может быть найдено, поэтому вот его статья для любопытных.


Можете ли вы кодировать требование для -50 длиной менее 50 символов?
Виктор Стафуса

1
@Victor Возможно, но> <> - гигантская боль в коде (забавная гигантская боль), поэтому мне нужно отдохнуть от нее.
SirCxyrtyx

@SirCxyrtyx это заставило меня посмеяться. Хорошо поиграл в гольф, сэр.
Gusdor

3

PHP, 118 113 112 111 (, -10 бонусных баллов = 101)

(вторая попытка, с ужасно предсказуемым rand()поведением и немного большей эффективностью)

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

Возможный результат:

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

PHP, 130 (, -10 бонусных баллов = 120)

(первая попытка)

Это, вероятно, все еще может быть гораздо более эффективным:

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

Если я заменю пробел подчеркиванием (для целей отображения), это будет возможным результатом:

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

Как ни странно, если я заменю rand(0,1)на rand()%2(PHP 5.4, в Windows XP), случайный результат всегда переключается с нечетного на четный, и наоборот, на каждой следующей итерации, что делает rand()тревожно предсказуемым, в этом смысле, внезапным. Эта «ошибка» известна с 2004 года . Не совсем уверен, что это точно такая же «ошибка».


3

J 42 символа - 50 -10 = -18

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

Объяснение, начиная справа (некоторые знания о поездах пригодятся):

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

Тенденция к центру, -50, пример более 1000 запусков:

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

Пример выполнения, выводящий ровно 30 байтов в каждой строке

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

Очень хорошее решение!
Reggaemuffin

Очень хороший вызов тоже!
jpjacobs

3

Python 2.7: 126 109 -10-50 = 49

Избавился от жестко заданной начальной точки - теперь начинается в случайной точке. Из-за этого мне понадобился randint, поэтому я решил использовать его вместо выбора для смещения. Для этого использовал (-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)

Некоторые отличные ответы здесь. Первая попытка в Python, думая об улучшениях. Не помогла необходимость в импорте.

-10 - да 30 символов + \ n в каждой строке

-50 - чем дальше от центра, тем больше вероятность перемещения в другую сторону (что достигается созданием списка с другим количеством смещений + / i)

Предыдущая попытка:

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)

Ваша forпетля может быть все на одной линии, но еще лучше, for i in[0]*30:а лучше все еще eval"..."*30.
mbomb007

2

Ява - 198 183 символа

Это простой, простой, прямой и не творческий гольф из примера, который вы привели в вопросе.

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

Пакетная обработка - (288 байт - 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-golfed:

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

Для вывода пробелов вместо подчеркивания - 372 байта -

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

Если вам нужна помощь со следующей логикой, конечно, это не самый экономичный способ (! R! Расширится до 1 или 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

Гольф до: 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 персонажа, бонусов нет

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

Пример выполнения:

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

2

Python 2.7 (126 - 10 (фиксированная длина) - 50 (центральная тенденция) = 66)

Следующая программа имеет тенденцию к центру над большей выборкой

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)

демонстрация

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

Как s = id (9)% 30 для посева. OS нуждается в импорте, хотя? И охватывает ли это полный диапазон 1-30? Ой, подождите ... * перечитывает неравенство вверху страницы *
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)

РЕДАКТИРОВАТЬ: Исправление для бонуса 50 очков и 10 очков.

РЕДАКТИРОВАТЬ 2: еще короче!


Вы можете объяснить, где вы получаете бонус в 50 баллов? Я не получаю это в настоящее время ...
reggaemuffin

@Kostronor Я только что видел изменения для требования. Похоже, я еще не набрал 50 очков.
aebabis

@acbabis, молодец! Вы можете сохранить несколько байтов (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(' '))}
Майкл М.

@ Майкл Спасибо за советы. Не могу получить инициализацию массива внутри forрабочей, хотя; пришлось использовать сделать некоторое время.
aebabis

2

D - 167, 162144 (154 - 10)

Гольф :

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

Без гольфа :

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

РЕДАКТИРОВАТЬ 1 - Я не совсем уверен, соответствует ли мой код бонусу -50 или нет. iне всегда начинается с середины, но во время forцикла точка никогда не перемещается более чем на 3 точки в любом направлении, поэтому, когда i она начинается около середины, все это также имеет тенденцию оставаться там.

РЕДАКТИРОВАТЬ 2 - Код теперь имеет право на бонус -10, так как он печатает массив из 29 символов, за которым следует LF, что в сумме дает ровно 30 символов на строку.


поскольку он печатает массив из 29 символов, за которым следует LF - это должно быть 30 символов, за которым следует LF.
Виктор Стафуса

@Victor ааа, спасибо за исправление, я неверно истолковал основной пост.
Тони Эллис

2

PowerShell, 77 - 10 - 50 = 17

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

Выход

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

Умный случайный. Вы могли бы использовать версию для гольфа $x=random 30;1..30|%{' '*($x+=,-1*$x+,1*(29-$x)|random)+'.'|% *ht 30}. 66 байт - 10 - 50 = 6 баллов
mazzy

2

R, 107 символов - бонус 60 очков = 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 это индекс точки. aэто массив из 30 пробелов. Начальная точка случайная (равномерно от 1 до 29). На каждой итерации мы случайным образом добавляем -1 или +1 к iсо взвешенными вероятностями: i-1для -1и 29-i для+1 (значения, поданные как вероятности, не нужно суммировать с единицей), что означает, что она имеет тенденцию ориентировать точку к центру, предотвращая ее снизу 1 или выше 29 (поскольку их вероятность падает до 0 в обоих случаях).

Пример запуска с _ пробелами вместо разборчивости:

> 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='')}
_______________________.______
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
_____________________.________
______________________._______
_____________________.________
______________________._______
_____________________.________
____________________._________
___________________.__________
____________________._________
___________________.__________
__________________.___________
_________________.____________
________________._____________
_______________.______________
______________._______________
_______________.______________
________________._____________
_________________.____________
________________._____________
_______________.______________
______________._______________

Если я не ошибаюсь, читая твой код, i может стать либо, 0либо 30нет?
user2846289

Да, вы правы, это может быть 30 (не больше, хотя), я изменю это.
plannapus

1
Это исправлено сейчас. Вероятность перехода от 1 до 0 или от 29 до 30 теперь равна 0. Случайная точка начала теперь между 1 и 29.
plannapus

Подсказка: вы можете сохранить еще 2 символа, заменив их s(1:29,1)на s(29,1).
Свен Хоэнштайн

@SvenHohenstein, ты прав, я всегда забываю об этом
забываю 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;}}}}

Выход

space заменено на _ на разборчивость.

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

Я почти уверен, что if...else if...elseв конце вашего кода можно получить меньший код. Кроме того, ваш вывод заставляет меня усомниться в том, что он находится посередине, но ваш код кажется правильным.
Виктор Стафуса

Забыл обновить вывод, когда я редактировал код. Это r.Next(30)<p?-1:1;делает это возможным. Не уверен, что вы можете пойти меньше с ifзаявлениями. switchявляется большим из-за обязательного break/ returnи финал elseтребует default:{}случая, и это также долго.
Gusdor

@Victor спасибо за вклад. я сделал некоторые правки.
Gusdor

Если pноль, то p+=r.Next(30)<p?-1:1;всегда будет 1, поэтому нет необходимости if(p==0). То же самое для p==29. pникогда не будет 30, так что вы можете избавиться от else if.
Виктор Стафуса

@ Виктор великий. Я сделаю эти изменения. Ta.
Gusdor

1

PHP

С бонусом за центрирование: 82 - 50 = 32

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

Для этой версии (старые версии ниже) убрана проверка мин / макс, как об этом говорится в центрирующем коде. rand(1,28)становится важным здесь, так как это позволяет$i++ толкать себя до 29 (фактический максимум).

редактировать: ненужные скобки, перемещенный код сдвига


Простой алгоритм центрирования: генерирует новое число от 0 до 29 и сравнивает его с текущим. Использует "вероятность" получения числа на большей стороне, чтобы привлечь к центру.

Фактический результат: (добавлена ​​нумерация строк)

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

Архивировано:

$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 персонажей

$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 символов


Меня немного впечатлило, что я сбрил 49 персонажей с моей первой версии ...
Йода,

бритые 44 персонажа сейчас. Что должно означать, что это было 39 в прошлый раз.
Йода

1

JavaScript ES6 125 - 10 (30 строк символов) - 50 (сдвиг к середине) = 65

У меня было прозрение, когда я поднимался на лифте в мой блок, поэтому мне пришлось его снять, прежде чем он оставил мою память ...

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

Небольшая переменная позиционная перетасовка и немного креативности для вычисления вероятности смещения, обозначенной x/t... (Спасибо, Костронор, за то, что указал на это!) Теперь я получаю бонус -50 за смещение к середине, и я также сделал стартовую позицию в пределах полный диапазон строки, что позволило мне побрить два байта!

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

Не правда ли, что случайность начальной позиции точки здесь ограничена 2 или 3 возможностями? И это то, что держит точку посередине (из-за очень короткого количества пробежек = 30) и, следовательно, стоит -50?
user2846289

Цитируя текст ОП : «Ваша программа начинается со случайной позиции х, и каждый ход сдвигает эту позицию случайным образом на 1 влево или вправо». Сначала определяется мой код, 15+r()*2который может быть любым от 15 до 16.9999999998 или около того, который может округляться до 17, дополнительный x+=r()<.5?-1:1бросает немного больше случайности, доводя его до диапазона от 14 до 18, так что технически это случайное число, которое находится в пределах определения того, что было задано ... Изгибая это правило, переворачиваем (+1, -1) в большинстве случаев вернет его к середине ...;)
WallyWest

Ну, на случайной вещи, вы меня поймали ... Это должно было быть «случайной позицией из всех возможных позиций», но это дает вам небольшое преимущество, так как 50 очков явно не применимы! Пожалуйста, перечитайте объяснение этого бонуса, фиксированные 0,5 процента не получите его!
Reggaemuffin

Действительный пункт, я буду пересматривать мой счет соответственно ...
WallyWest

Код @Kostonor обновлен с правильным решением, обновил счет соответственно!
WallyWest

1

к, 53 - 10 - 50 = -7

Решение 1

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

использование

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

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

Решение 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 байт

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

Я все еще думаю о 50-байтовом бонусе.

Объяснение:

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

Комментарии и советы приветствуются.


К сожалению, ваше решение не подходит, сравните ваши результаты с результатами других решений. Сместить точку на один символ.
reggaemuffin

@ Костронор О! ой! Мне так жаль! Я забыл прочитать эту часть вопроса! Я постараюсь разработать новую версию в ближайшее время. Спасибо за указание!
Гауранг Тандон

Программа @Kostronor отредактирована.
Гауранг Тандон

1

JavaScript

114 символов - 10 (30 строк символов) - 50 (потяните точку к середине) = 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('-'))

Однако я заметил, что награда в 10 символов за заполнение строк до 30 символов может быть плохой сделкой; так:

102 символа - 50 (потяните точку к середине) = 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('-'))

Спасибо @WallyWest за условное упрощенное направление вытягивания f()>k/29?1:-1, мой первый черновик использовал два вложенных условных выражения .


1

Ракетка 227 байт (-10 для 30 символов, -50 для перехода к средней линии = 167)

На каждом шаге точка в два раза чаще перемещается к средней линии, чем от нее:

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

Тестирование:

(println "012345678901234567890123456789")
(f)

Выход:

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

Отличное решение! Ракетка действительно интересная. Вы можете дать себе 50 бонусных баллов и проверить,
подаете
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.