Ваша программа должна распечатать несколько пробелов, за которыми следуют точка и символ новой строки. Количество пробелов - это позиция 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
.Ответы:
APL, 39 - 10 - 50 = –21
Проверено на Dyalog с
⎕IO←1
и,⎕ML←3
но оно должно быть довольно портативным.объяснение
На каждом этапе этот код решает, перемещать ли точку влево или вправо, в зависимости от вероятности того, что выбранное случайное число (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
и имея результат каждой итерации в качестве⍵
аргумента аккумулятора ( ) для следующего. Второй и следующий входные аргументы (⍺
), а также конечный результат игнорируются. Оказывается, это намного короче, чем обычный рекурсивный вызов с охраной.Пример запуска
источник
+/2×⍳9
читается как «сумма: два раза: натуральное число до 9», но выполнено в обратном порядке.⎕←30↑...
напечатает 30 символов плюс символ новой строки, независимо от того, в какой строке находится...
Mathematica 138 - 10 - 50 = 78
Я не публикую это, потому что думаю, что это особенно хорошо, но по другим причинам. Он использует определение Марковского процесса с матрицей перехода, предназначенной для центрирования шара.
Использование марковского процесса в Mathematica позволяет нам вычислить некоторые полезные статистические данные , как вы увидите ниже.
Сначала код (пробелы не нужны):
Некоторые выводы:
Матрица перехода, которую я использовал:
Но, как я уже сказал, интересная часть заключается в том, что использование
DiscreteMarkovProcess[]
позволяет нам получить хорошее представление о том, что происходит.Давайте посмотрим на вероятность того, что мяч будет
15
в любое время,t
начиная с определенного случайного состояния :Вы можете видеть, что он колеблется между 0 и значением около 0,3, потому что в зависимости от начального состояния вы можете достичь только 15 с нечетным или четным числом шагов :)
Теперь мы можем сделать то же самое, но сказать Mathematica рассмотреть статистику, начиная со всех возможных начальных состояний. Какова вероятность быть
15
через какое-то времяt
?Вы можете видеть, что это также колеблется ... почему? Ответ прост: в интервале
[1, 29]
больше нечетных, чем четных чисел :)Колебания почти исчезнут, если мы спросим вероятность того, что мяч находится в
14 OR 15
:И вы могли бы также попросить предел (в смысле Чезаро) вероятности состояния:
О, ну, возможно, я заслуживаю некоторых отрицательных ответов за такой не по теме ответ. Не стесняйтесь.
источник
Bash, оценка 21 (81 байт - 50 бонусов - 10 бонусов)
В этом ответе точка «вытягивается» назад к середине. Это можно проверить путем жесткого кодирования начальной точки в 0 или 30.
источник
{1..30}
на{P..m}
o
есть1
иRANDOM%30
возвращается0
? И на следующей итерации тоже?Рубин
696664-60 = 4Образец:
источник
i=rand 30;
вместоi=rand(30);
.Smalltalk,
161159145-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 бита ;-)).
украдя идею из версии Ruby (thanx & Up @fipgr), я могу избавиться от проверки min / max:
Вывод: (я вручную добавил номера столбцов и вертикальные столбцы; код выше не генерирует их)
источник
С 86
Предполагая, что посев
rand()
функция заполнения не требуется.Объяснение:
В 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. Заранее спасибо. (Извините, я не программист на Си.)rand()%2
тем, что оно очень предсказуемо (нечетные / четные повороты)? Я попробовал вашеrand()%2
в своем решении PHP, и оно показало это очень предсказуемое поведение (в отличие отrand(0,1)
. Поскольку PHP много использует библиотеки C (если я прав), мне было интересно, имеет ли ваша программа C тот же «недостаток» .rand()
функцию. В C, еслиrand()
явно не выделен, он всегда использует одно и то же начальное число каждый раз. Вот почему это предсказуемо. Если бы мне пришлось посеять это, я могу сделать,srand(time());
что стоит 14 символовrand()
не нужно засеваютsrand()
больше, но все же показывает , что это странное поведение.Java:
204183182176175 символов - 10 - 50 = 115Во-первых, позиция точки должна быть
0 < x < 30
, то есть [1-29]. Это генерирует число от 0 до 28, равномерно распределенное, и для целей этой программы [0-28] имеет тот же эффект, что и [1-29]:Я лично предпочел бы, чтобы это было нормально распределено около 14, но мой ответ был бы длиннее:
Во-вторых, этот код гарантирует, что он будет посередине:
Вероятность получить +1 тем больше, чем меньше значение
i
, а у нас есть обратное для -1. Еслиi
0, вероятность получения +1 составляет 100%, а вероятность получения -1 составляет 0%. Еслиi
это 28, произойдет обратное.В-третьих, заменив
32
в конце на,'_'
чтобы легче видеть вывод, мы видим, что каждая строка имеет 30 символов плюс новую строку:Спасибо @VadimR (теперь user2846289) за то, что он указал на недоразумение в предыдущей версии.
Спасибо @KevinCruijssen за 6 символов, даже спустя более двух с половиной лет после того, как этот ответ был первоначально опубликован.
источник
i
добраться до0
незаконна, не так ли?i
в диапазоне [0-29]. Это эквивалентно [1-30] или [288-317], результат будет таким же. Важно то, что в интервале есть 30 целых чисел [0-29].i
не может быть0
. Я понимаю, что это все о веселье, но все же это грустно.i
получает на1
начальном этапе, и на первой итерацииMath.random()
это0
, тоi
получает0
. Пожалуйста, не поймите меня неправильно, дело не в вашем ответе. Скорее о моей неспособности читать большинство языков, кроме C-like. Тогда без всякой реакции (за исключением возражений) на ошибки, откуда мне знать, правы они или нет?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 пробелов, который соответствует интересующему столбцу.источник
RandomChoice[]
> <>, 358 - 10 = 348
Это не победит в Codegolf, но это работает. (В Windows 7 с этим интерпретатором , который реализует инструкцию «p» иначе, чем это определяет страница esolang)
Название этого языка не может быть найдено, поэтому вот его статья для любопытных.
источник
PHP,
118113112111 (, -10 бонусных баллов = 101)(вторая попытка, с ужасно предсказуемым
rand()
поведением и немного большей эффективностью)Возможный результат:
PHP, 130 (, -10 бонусных баллов = 120)
(первая попытка)
Это, вероятно, все еще может быть гораздо более эффективным:
Если я заменю пробел подчеркиванием (для целей отображения), это будет возможным результатом:
Как ни странно, если я заменю
rand(0,1)
наrand()%2
(PHP 5.4, в Windows XP), случайный результат всегда переключается с нечетного на четный, и наоборот, на каждой следующей итерации, что делаетrand()
тревожно предсказуемым, в этом смысле, внезапным. Эта «ошибка» известна с 2004 года . Не совсем уверен, что это точно такая же «ошибка».источник
J 42 символа - 50 -10 = -18
Объяснение, начиная справа (некоторые знания о поездах пригодятся):
Тенденция к центру, -50, пример более 1000 запусков:
Пример выполнения, выводящий ровно 30 байтов в каждой строке
источник
Python 2.7:
126109 -10-50 = 49Избавился от жестко заданной начальной точки - теперь начинается в случайной точке. Из-за этого мне понадобился randint, поэтому я решил использовать его вместо выбора для смещения. Для этого использовал (-1) ** булевый трюк.
Некоторые отличные ответы здесь. Первая попытка в Python, думая об улучшениях. Не помогла необходимость в импорте.
-10 - да 30 символов + \ n в каждой строке
-50 - чем дальше от центра, тем больше вероятность перемещения в другую сторону (что достигается созданием списка с другим количеством смещений + / i)
Предыдущая попытка:
источник
for
петля может быть все на одной линии, но еще лучше,for i in[0]*30:
а лучше все ещеeval"..."*30
.Ява -
198183 символаЭто простой, простой, прямой и не творческий гольф из примера, который вы привели в вопросе.
источник
Пакетная обработка - (288 байт - 10) 278
Un-golfed:
Для вывода пробелов вместо подчеркивания - 372 байта -
Если вам нужна помощь со следующей логикой, конечно, это не самый экономичный способ (! R! Расширится до 1 или 2) -
Гольф до:
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
источник
J, 42 персонажа, бонусов нет
Пример выполнения:
источник
Python 2.7 (126 - 10 (фиксированная длина) - 50 (центральная тенденция) = 66)
Следующая программа имеет тенденцию к центру над большей выборкой
демонстрация
источник
Javascript
125737260 (120 - 50 - 10)РЕДАКТИРОВАТЬ: Исправление для бонуса 50 очков и 10 очков.
РЕДАКТИРОВАТЬ 2: еще короче!
источник
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
рабочей, хотя; пришлось использовать сделать некоторое время.D -
167,162144 (154 - 10)Гольф :
Без гольфа :
РЕДАКТИРОВАТЬ 1 - Я не совсем уверен, соответствует ли мой код бонусу -50 или нет.
i
не всегда начинается с середины, но во времяfor
цикла точка никогда не перемещается более чем на 3 точки в любом направлении, поэтому, когдаi
она начинается около середины, все это также имеет тенденцию оставаться там.РЕДАКТИРОВАТЬ 2 - Код теперь имеет право на бонус -10, так как он печатает массив из 29 символов, за которым следует LF, что в сумме дает ровно 30 символов на строку.
источник
PowerShell, 77 - 10 - 50 = 17
Выход
источник
$x=random 30;1..30|%{' '*($x+=,-1*$x+,1*(29-$x)|random)+'.'|% *ht 30}
. 66 байт - 10 - 50 = 6 балловR, 107 символов - бонус 60 очков = 47
i
это индекс точки.a
это массив из 30 пробелов. Начальная точка случайная (равномерно от 1 до 29). На каждой итерации мы случайным образом добавляем -1 или +1 кi
со взвешенными вероятностями:i-1
для-1
и29-i
для+1
(значения, поданные как вероятности, не нужно суммировать с единицей), что означает, что она имеет тенденцию ориентировать точку к центру, предотвращая ее снизу 1 или выше 29 (поскольку их вероятность падает до 0 в обоих случаях).Пример запуска с
_
пробелами вместо разборчивости:источник
i
может стать либо,0
либо30
нет?s(1:29,1)
наs(29,1)
.C # 184 - 10 - 50 = 123
Выход
space заменено на _ на разборчивость.
источник
if...else if...else
в конце вашего кода можно получить меньший код. Кроме того, ваш вывод заставляет меня усомниться в том, что он находится посередине, но ваш код кажется правильным.r.Next(30)<p?-1:1;
делает это возможным. Не уверен, что вы можете пойти меньше сif
заявлениями.switch
является большим из-за обязательногоbreak
/return
и финалelse
требуетdefault:{}
случая, и это также долго.p
ноль, тоp+=r.Next(30)<p?-1:1;
всегда будет 1, поэтому нет необходимостиif(p==0)
. То же самое дляp==29
.p
никогда не будет 30, так что вы можете избавиться отelse if
.PHP
С бонусом за центрирование: 82 - 50 = 32
Для этой версии (старые версии ниже) убрана проверка мин / макс, как об этом говорится в центрирующем коде.
rand(1,28)
становится важным здесь, так как это позволяет$i++
толкать себя до 29 (фактический максимум).редактировать: ненужные скобки, перемещенный код сдвига
Простой алгоритм центрирования: генерирует новое число от 0 до 29 и сравнивает его с текущим. Использует "вероятность" получения числа на большей стороне, чтобы привлечь к центру.
Фактический результат: (добавлена нумерация строк)
Архивировано:
$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 символовисточник
JavaScript ES6 125 - 10 (30 строк символов) - 50 (сдвиг к середине) = 65
У меня было прозрение, когда я поднимался на лифте в мой блок, поэтому мне пришлось его снять, прежде чем он оставил мою память ...
Небольшая переменная позиционная перетасовка и немного креативности для вычисления вероятности смещения, обозначенной
x/t
... (Спасибо, Костронор, за то, что указал на это!) Теперь я получаю бонус -50 за смещение к середине, и я также сделал стартовую позицию в пределах полный диапазон строки, что позволило мне побрить два байта!источник
15+r()*2
который может быть любым от 15 до 16.9999999998 или около того, который может округляться до 17, дополнительныйx+=r()<.5?-1:1
бросает немного больше случайности, доводя его до диапазона от 14 до 18, так что технически это случайное число, которое находится в пределах определения того, что было задано ... Изгибая это правило, переворачиваем (+1, -1) в большинстве случаев вернет его к середине ...;)к, 53 - 10 - 50 = -7
Решение 1
использование
Решение 2
источник
Scala, 95 - 10 = 85 байт
Я все еще думаю о 50-байтовом бонусе.
Объяснение:
источник
Javascript, 125 (135 - 10)
Комментарии и советы приветствуются.
источник
JavaScript
114 символов - 10 (30 строк символов) - 50 (потяните точку к середине) = 54
Однако я заметил, что награда в 10 символов за заполнение строк до 30 символов может быть плохой сделкой; так:
102 символа - 50 (потяните точку к середине) = 52
Спасибо @WallyWest за условное упрощенное направление вытягивания
f()>k/29?1:-1
, мой первый черновик использовал два вложенных условных выражения .источник
Ракетка 227 байт (-10 для 30 символов, -50 для перехода к средней линии = 167)
На каждом шаге точка в два раза чаще перемещается к средней линии, чем от нее:
Ungolfed:
Тестирование:
Выход:
источник