Зсувна точка


16

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

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

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

Редагувати: 50 бонусних балів призначені для виведення точки до середини. Наприклад, це стосується, якщо крапка знаходиться на x = 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.
Віктор Стафуса

Я думаю, що оригінальний код правильний.
користувач2846289

це правильно, тому що я зсуваю перший і друк. тож навіть якщо випадкове значення перевищує межу, якщо спочатку виправить, а потім надрукує.
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 - чудова мова для гольфу (хоча для мене важко читати); Вгору!
blabla999

@ blabla999 APL має багато загальних символів та деякі дивні символи, але коли ви засвоїте їх функції, мова легко читається та пише. Звичайно простіше, що ASCII шум "гольф" мов, але я б ризикнути сказати, що це навіть простіше, ніж звичайні мови. Синтаксис дуже регулярний, у вас є лише одне правило: вирази виконуються справа наліво, так що їх можна читати зліва направо: +/2×⍳9читається "сума: два рази: натурали до 9", але це виконані протилежно.
Тобія

Це я чи є 31 символ на рядок?
Гусдор

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

12

Математика 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}

Деякі результати:

Mathematica graphics

Я використовував матрицю переходу:

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

Mathematica graphics

Але, як я вже сказав, цікавою є те, що використання 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]

Mathematica graphics

Ви можете бачити, що вона коливається між 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]

Mathematica graphics

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

Коливання майже не зникає, якщо ми запитаємо про ймовірність того, що куля знаходиться у 14 OR 15:

Mathematica graphics

І ви також можете попросити обмежити (у сенсі Цесаро) ймовірності стану:

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

Mathematica graphics

О, ну, мабуть, я заслуговую на те, щоб відповісти на тему, що не відповідає темі. Почувайся вільно.


2
Це не найкоротше, але це дуже круто.
Kasra Rahjerdi

Оновлено, і тепер ваш рахунок вже не 2222 ...
cormullion

@cormullion Дякую! Ви можете скасувати це, відмовившись важко :)
Доктор Белісарій,

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.


Гарне рішення! Але, будь ласка, не жорстко
кодуйте

1
@Kostronor - ой, я пропустив це і тепер це виправив.
Цифрова травма

2
зберегти символ, замінивши {1..30}на{P..m}
Geoff Ріді

Що робити, якщо oє 1і RANDOM%30повертається 0? І на наступній ітерації теж?
користувач2846289

@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

Малий розмова , 161 159 145-60 = 85

всі стовпці завдовжки 30 годин (працюють у змінному рядку b);

Шанс випадкового руху регулюється зміщенням значення rnd з p (rnd (0..29) -p), приймаючи знак (-1/0/1), а потім регулюючи до (-1 / + 1) через (-1 | 1), який приймається як дельта переміщення (ефективно обчислює: знак x x = = ifTrue: -1 ifFalse: 1). Оскільки ST використовує індексацію на основі 1, я повинен відкоригувати всі строкові рефіскації на +1 (plz оцінює -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]

висновок: (я вручну додав номери col і вертикальні смуги після цього; код вище не створює їх)

 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 такий самий "недолік" .
Гідний даблер

@fireeyedboy Я функцію не закладав rand(). Якщо C rand()не висівається явно, він завжди використовує те саме насіння. Ось чому це передбачувано. Якщо мені довелося srand(time());
посіяти

Але чи настільки передбачувано, що воно переходить від непарного до парного при кожному наступному дзвінку? Заяви PHP rand()більше не потребують посіву srand(), але все-таки демонструють це дивне поведінку.
Гідний даблер

4

Ява: 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 у нас навпаки. Якщо iдорівнює 0, ймовірність отримати +1 становить 100%, а ймовірність отримати -1 - 0%. Якщо i28, відбудеться навпаки.

По-третє, замінивши 32в кінці на, '_'щоб побачити вихід легше, ми бачимо, що кожен рядок містить 30 символів плюс новий рядок:

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

Дякуємо @VadimR (зараз користувач2846289) за вказівку на непорозуміння у попередній версії.

Завдяки @KevinCruijssen за те, що голив 6 персонажів, навіть через більше ніж два з половиною роки після того, як ця відповідь була спочатку опублікована.


Але iпотрапляти до 0незаконно, чи не так?
користувач2846289

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

"Кількість пробілів - це х положення вашої крапки, визначене з 0 <x <30", тобто кількість пробілів (або точка-позиція на основі 0) дорівнює 1..29. iне може бути 0. Я розумію, що це все про веселощі, але все одно це сумно.
користувач2846289

@VadimR, О, дякую. Виправлено. Це означає, що крапка ніколи не буде знаходитись у правій позиції, але все одно, саме це було зазначено.
Віктор Стафуса

Вибачте, але це нічого не виправило. Уявіть, що iотримується 1спочатку, а спочатку ітерація Math.random()є 0, потім iотримує 0. Будь ласка, не зрозумійте мене неправильно, справа не у вашій відповіді. Скоріше про мою нездатність читати більшість мов, крім C-подібних. Тоді без жодної реакції (за винятком заявок) на помилки, як я можу знати, що вони праві чи ні?
користувач2846289

3

Математика 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

dot


Гарне використання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 це змусило насміхатися. Добре гольф сер.
Гусдор

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

Пітон 2.7: 126 109 -10-50 = 49

Позбувся важко закодованої вихідної точки - тепер починається у випадковій точці. Через це мені знадобився рандінт, тому я вирішив використовувати це замість вибору для компенсації. Для цього використав фокус (-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

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

Без гольфу:

@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 для висіву насіння. ОС потребує імпорту, хоча? І чи охоплює це повний діапазон 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 балів.

EDIT 2: Ще коротше!


Ви можете пояснити, де ви отримуєте бонус на 50 балів? Я не отримую цього на даний момент ...
reggaemuffin

@Kostronor Я щойно побачив редагування вимоги. Схоже, я ще не набрав 50 балів.
аебабіс

@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(' '))}
Майкл М.

@Michael Дякую за поради. Не вдалося отримати масив init всередині forробочого; довелося використовувати час робити.
аебабіс

2

D - 167, 162, 144 (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;
    }
}

EDIT 1 - Я не зовсім впевнений, чи мій код відповідає бонусу -50 чи ні. iне завжди починається в середині, але під час forциклу, точка ніколи не рухається більше як 3 місця або напрямку, тому , коли i ж почати ближче до середини, все це має тенденцію залишатися там.

EDIT 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 балів
маззи

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, ні?
користувач2846289

Так, ти маєш рацію, це може бути 30 (не більше), я змінити це.
планнапус

1
Це зараз виправлено. Ймовірність перейти від 1 до 0 або перейти з 29 до 30 зараз становить 0. Випадкова відправна точка зараз між 1 і 29
планнапус

Підказка: Ви можете зберегти ще 2 символи, замінивши s(1:29,1)на s(29,1).
Свен Гогенштайн

@SvenHohenstein ти маєш рацію, я завжди забуваю про це
плановий

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:{}справа, і це також довго.
Гусдор

@Victor дякую за вклад. я вніс деякі зміни.
Гусдор

Якщо pдорівнює нулю, p+=r.Next(30)<p?-1:1;завжди буде 1, тому немає необхідності if(p==0). Дітто для p==29. pніколи не буде 30, так що ви можете позбутися від else if.
Віктор Стафуса

@Victor grand. я погано вношу ці зміни. Та.
Гусдор

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

Для цієї версії (старі версії нижче) зняли перевірку min / max, як це було зроблено в коді центрування. 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 персонажів з моєї першої версії ...
Yoda

зараз поголений 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?
користувач2846289

Цитуючи текст ОП : "Ваша програма починається з випадкової х позиції, і кожен поворот зміщує цю позицію випадковим чином на 1 вліво або вправо" Мій код спочатку визначається, при 15+r()*2якому може бути що-небудь від 15 до 16.9999999998 або близько того, що могло б обійти до 17. Додатковий x+=r()<.5?-1:1кидає трохи більше випадковості, доводячи його до діапазону від 14 до 18, тобто технічно випадкове число, яке знаходиться у визначенні того, що було запропоновано ... Згинаючи це правило, фліп (+1, -1) у більшості випадків поверне його до середини ...;)
WallyWest

Ну, у випадковому випадку ви мене зрозуміли ... Малося на увазі це "випадкова позиція з усіх можливих позицій", але це дає не велику перевагу, оскільки 50 балів явно не застосовуються! Прочитайте, будь ласка, пояснення щодо цього бонусу, фіксованих 0,5 відсотків не отримуйте!
reggaemuffin

Дійсний бал, я відповідно
повторюю

Кодекс Костонора оновлено правильним рішенням, відповідно оновлений рахунок!
WallyWest

1

k, 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 О! ой! Мені так шкода! Я забув прочитати ту частину питання! Я спробую незабаром розробити нову версію. Дякуємо, що вказали!
Gaurang Tandon

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

Безголівки:

(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 бонусних балів і перевірити, чи подаєте ви заявку на додаткові 10 :-)
reggaemuffin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.