О серии
Во-первых, вы можете относиться к этому, как к любому другому вызову для игры в гольф, и отвечать на него, не беспокоясь о серии вообще. Тем не менее, существует таблица лидеров по всем задачам. Вы можете найти список лидеров вместе с дополнительной информацией о серии в первом посте .
Несмотря на то, что у меня есть ряд идей для этой серии, будущие проблемы еще не заложены. Если у вас есть какие-либо предложения, пожалуйста, сообщите мне об этом в соответствующей песочнице .
Отверстие 2: числа из нормального распределения
Я не могу поверить, что это еще не сделано! Вы должны генерировать случайные числа, опираясь на нормальное распределение . Некоторые правила (большинство из них, вероятно, автоматически охватываются большинством представлений, но некоторые из них применяются для обеспечения согласованности результатов между совершенно разными языками):
В качестве входных данных вы должны взять два неотрицательных целых числа : начальное число
S
и количествоN
возвращаемых чисел. Выходными данными должен быть списокN
чисел с плавающей запятой, взятый из нормального распределения со средним 0 и дисперсией 1 . Всякий раз, когда вашему представлению дается одно и то же семя,S
оно должно давать одно и то же число. В частности, если он вызывается один раз с и один раз с , первые записи двух выходов должны быть идентичны. Кроме того, как минимум 2 16 различных значений должны давать разные последовательности.(S, N1)
(S, N2)
min(N1, N2)
S
Вы можете использовать любой встроенный генератор случайных чисел, который задокументирован, для рисования чисел из (приблизительно) равномерного распределения, при условии, что вы можете передать
S
его, и он поддерживает как минимум 2 16 различных начальных чисел . Если вы это сделаете, RNG сможет вернуть не менее 2 20 различных значений для любого заданного вами номера.- Если имеющийся у вас однородный ГСЧ имеет меньший диапазон, не пригоден для посева или поддерживает слишком мало семян, вы должны сначала создать однородный ГСЧ с достаточно большим диапазоном поверх встроенного, либо вы должны реализовать свой собственный подходящий ГСЧ, используя семя. Эта страница может быть полезна для этого.
- Если вы не реализуете установленный алгоритм генерации нормальных распределений, пожалуйста, включите подтверждение правильности. В любом случае выбранный вами алгоритм должен давать теоретически точное нормальное распределение (за исключением ограничений базовых типов данных PRNG или ограниченной точности).
- Ваша реализация должна использовать и возвращать либо числа с плавающей запятой (шириной не менее 32 бит), либо числа с фиксированной запятой (шириной не менее 24 бит), и все арифметические операции должны использовать полную ширину выбранного типа.
- Вы не должны использовать какие-либо встроенные функции, непосредственно связанные с нормальным распределением или гауссовыми интегралами, такие как функция Error или ее обратное.
Вы можете написать полную программу или функцию и получать ввод через STDIN, аргумент командной строки, аргумент функции или приглашение и производить вывод через возвращаемое значение или печатать в STDOUT (или ближайшую альтернативу).
S
и N
будут неотрицательными целыми числами, каждое меньше 2 20 . Вывод может быть в любом удобном, однозначном списке или строковом формате.
Это код гольф, поэтому выигрывает самое короткое представление (в байтах). И, конечно же, самая короткая заявка для каждого пользователя также войдет в общую таблицу лидеров серии.
Leaderboard
Первый пост серии генерирует таблицу лидеров.
Чтобы убедиться, что ваши ответы отображаются, начните каждый ответ с заголовка, используя следующий шаблон уценки:
# Language Name, N bytes
где N
размер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(Язык в настоящее время не отображается, но фрагмент требует и анализирует его, и я могу добавить таблицу лидеров по языкам в будущем.)
Ответы:
Dyalog APL, 33 байта
{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕
Box-Muller :
источник
⎕rl
чтобы быть,S+1
потому что⎕rl←0
имеет особое значение.+1
, все, что он говорит, это то, что вам нужно поддерживать как минимум 2 ^ 16 различных значений. Так что работать правильно в диапазоне [1..2 ^ 16] должно быть в порядке.R, 68 байт
При этом используется
runif()
функция, которая генерирует случайные отклонения от равномерного распределения.set.seed()
Начальное число для генерации случайных чисел задается с помощью , который по умолчанию использует алгоритм Мерсенна-Твистера с периодом 2 ^ 19937-1.Результатом является вектор R длины N, содержащий вычисленные стандартные отклонения нормалей.
При этом используется метод Бокса-Мюллера: для двух независимых однородных случайных величин U и V,
источник
f=
не указывать (функция не обязательно должна называться, если на вашем языке нет названных функций).Error: unexpected '}' in "f=fu...
кроме того, вы уверены, что получаете те же первые номера, если вы звонитеf(0,1)
иf(0,2)
?Дьялог АПЛ,
4234Эта функция принимает
S
левый аргумент иN
правый аргумент.Это реализация преобразования Бокса-Мюллера, использующая встроенный случайный оператор Dyalog APL
?
, который по умолчанию представляет собой твистер Мерсенна, который возвращает 64-битные значения, которых должно быть достаточно.Объяснение:
⎕RL←⍺
: установить случайное начальное значение в⍺
.?⍵2⍴0
: генерировать⍵
пары случайных чисел от 0 до 1.{
...}/
: применить следующую функцию к каждой паре:(.5*⍨¯2×⍟⍺)×1○⍵×○2
: вычислитьZ0
значение (sqrt(-2 ln ⍺)×cos(2π⍵)
).источник
?0
возвращается число с плавающей точкой от 0 до 1.Perl, 67
Box-Muller как и в других записях.
f
принимает параметры в порядкеS, N
.Использование:
источник
Java,
164161 байтЭто требует ввода через функцию и вывода через стандартный вывод. Он использует метод Бокса-Мюллера.
источник
s=0;s++<n;
->;n-->0;
?Commodore 64 Basic,
767063 байтаПоскольку набор символов PETSCII содержит некоторые символы, отсутствующие в Юникоде, я сделал замены:
/
=SHIFT+N
,┌
=SHIFT+O
,●
=SHIFT+Q
,╮
=SHIFT+I
,─
=SHIFT+E
Это реализует стандартное преобразование Бокса-Мюллера для генерации чисел; Я выбрал половину преобразования sin (x), потому что Commodore 64 Basic имеет двухсимвольный ярлык для
sin()
, но не дляcos()
.Хотя в руководстве указано иное, значение аргумента для
RND
имеет значение: если передается отрицательное число, генератор случайных чисел не просто повторно засеивается, он снова засевается этим числом . Это значительно упрощает заполнение: вместо того, чтобы использоватьPOKE
пять ячеек памяти, мне просто нужно сделать бесполезный вызовRND
, который сокращает код с двух строк / 121 байта до 1 строки / 76 байтов.Редактировать: отыграть шесть байтов, поняв, что я могу объединить два
INPUT
утверждения, и что пробел послеTO
был необязательным.Редактировать: Гольф еще семь раз: Commodore Basic, фактически, имеет Pi как встроенную константу, и его даже можно печатать на современной клавиатуре (
SHIFT+PgDn
на случай, если вам интересно).источник
80386 машинный код, 72 байта
Hexdump кода:
Вот исходный код (может быть скомпилирован Visual Studio):
Здесь я использую генератор случайных чисел Лемера . Он использует следующий алгоритм:
Здесь 4294967291 - это большое (2 ^ 32-5) простое число, а 116 - это небольшое (меньше 128; см. Ниже) число, являющееся его примитивным корнем . Я выбрал примитивный корень с более или менее случайным распределением нулей и единиц в двоичном представлении (01110100). Этот ГСЧ имеет максимально возможный период 4294967290, если начальное число отлично от нуля.
Относительно небольшие числа, которые я здесь использовал (116 и 4294967291, которые можно также представить как -5), позволяют мне воспользоваться
lea
кодировкой команд:Он состоит из 3 байтов, если числа могут помещаться в 1 байт.
Умножение и деление используют
edx
и вeax
качестве их рабочих регистров, поэтому я сделалseed
второй параметр функции (fastcall
соглашение о вызовах используетedx
для передачи второго параметра). Кроме того, передается первый параметрecx
, который является хорошим местом для хранения счетчика: цикл может быть организован в 1 инструкцию!Чтобы преобразовать целое число в число с плавающей запятой, я использовал представление чисел с плавающей запятой одинарной точности: если я установлю старшие 9 бит (экспонента) в битовую комбинацию
001111111
и оставлю 23 младших бита случайными, я буду получить случайное число в диапазоне 1 ... 2. Я взял идею отсюда . Чтобы установить старшие 9 бит, я использовал некоторые битыebx
:Чтобы сгенерировать два случайных числа, я использовал вложенный цикл из 2 итераций. Я организовал это с
xor
:Код с плавающей точкой реализует преобразование Бокса-Мюллера .
источник
Хаскелл, 118
144Пример использования:
Тип возвращаемого значения
random
ограниченFloat
, что позволяетrandom
генерировать равномерное число с плавающей точкой в [0, 1). С тех пор это просто формула Бокса-Мюллера с некоторой бессмысленной магией для генерации списка.источник
Golflua, 63
70Информация о Golflua и инструкции.
Возвращает таблицу, содержащую значения. В примере, который я использую
~T.u( )
, то же самое, что иreturn table.unpack( )
в lua.Многие символы были сохранены путем установки среды функции
M
(иначеmath
).источник
САС, 108
Я уже опубликовал ответ в R, который короче этого, но на PPCG очень мало ответов SAS, так почему бы не добавить еще один?
С некоторым пробелом:
Это определяет макрос, который можно назвать как
%f(5, 3)
. Макрос выполняет шаг данных, который циклически перебирает целые числа от 1 до N, и на каждой итерации он вычисляет случайное нормальное отклонение, используя Box-Muller, и печатает его в журнал, используяput
инструкцию.SAS не имеет встроенной функции для pi, поэтому лучшее, что мы можем сделать, - это приблизить ее арктангенсом.
ranuni()
Функция (которая одобряется , но требуется несколько меньше символов , чем новая функция) возвращает случайное число из равномерного распределения. Документация SAS не дает много подробностей о реализации ГСЧ, за исключением того, что имеет период 2 ^ 31-2.В макросах SAS на макропеременные ссылаются с предшествующим
&
и разрешают их значения во время выполнения.Как вы, вероятно, засвидетельствовали, SAS редко является реальным соперником в соревнованиях по коду-гольфу .
источник
Ява, 193 байта
Хотя это не побеждает нынешнего лидера Java, я решил опубликовать в любом случае, чтобы показать другой метод расчета. Это версия OpenJDK для гольфа
nextGaussian()
.С переносами строк:
источник
(s,n)->{java.util.Random r=new java.util.Random(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*r.nextFloat()-1)*v)v=2*r.nextFloat()-1;}
T-SQL, 155 байт
Используйте с EXEC RS, N, потому что в T-SQL нет STD_IN, где S и N - начальное число и N соответственно. S будет выдавать «случайные» (RAND (seed) - очень плохая реализация случайных чисел) последовательности, когда S> 2 ^ 16 (возможно, до этого, но я не буду это гарантировать). Пока использует Box-Muller, как и большинство решений. 8388607 равен 2 ^ 23-1, что, как мы надеемся, должно генерировать 2 ^ 20 различных значений.
источник
Powershell, 164 байта
То же самое, что и большинство ответов с Box-Muller. Не очень опытный с Powershell, поэтому любая помощь в гольф будет оценена.
источник
Рубин, 72 байта
Вход (как лямбда-функция):
Выход:
PS: я хотел бы знать, может ли это быть дальше в гольфе. Я просто новичок.
источник
Матлаб, 77
Первый вход должен быть
n
, второйs
.источник
Октава,
919688 байтИли с пробелами:
Установите семена впереди и используйте метод Бокса-Мюллера.
NB. Octave позволяет генерировать массивы случайных чисел и может использовать стандартные операции над этими массивами, которые создают выходные данные массива.
.*
Оператор является элемент-на-элементом умножение двух массивов для получения результата.источник
n(0,1)
иn(0,2)
получаете разные первые номера, не так ли?Pyth, 32 байта
Python не используется сейчас в супер-кавычках из-за новых функций, которые есть у Pyth. Еще один Бокс-Мюллер.
Это пространство в начале важно.
Похоже, что посев не работает в онлайн-переводчике, но в локальной версии он работает нормально.Онлайн-переводчик, похоже, исправлен, так что вот постоянная ссылка: постоянная ссылкаисточник
.nZ
), которая не была реализована, когда был задан вопрос. (Он был фактически реализован сегодня.) Поэтому этот ответ не должен быть частью конкурса ( meta.codegolf.stackexchange.com/questions/4867/… ).STATA, 85 байт
Принимает ввод через стандартный вход (сначала S, затем N). Устанавливает начальное значение в S. Устанавливает число наблюдений в N. Создает переменную и устанавливает ее значение в качестве значения преобразования Бокса-Мюллера (спасибо @Alex за его показ). Затем перечисляет все наблюдения в таблице с заголовком столбца a и номерами наблюдений рядом с ними. Если это не хорошо, дайте мне знать, и я могу удалить заголовки и / или номера наблюдений.
источник
R, 89 байт
Я знаю, что R уже был сделан, но я хотел показать другой подход, чем Box-Muller, который использовали все остальные. Мое решение использует Центральную предельную теорему .
источник
a
в вашем коде, чтобы результат был «честным».)TI-Basic, 74 байта
На
¹
самом деле это обратный оператор.источник
Perl,
150108107 байтПри этом используется полярный метод Марсалья . Вызывается с помощью f (S, N).
Перенес задание
$a
в расчет$c
.107:
Убран запасной номер для хранения и определения
$b
.108:
150:
источник
Свифт,
144142Ничего умного, просто видя, как работает Swift.
Я надеялся, что смогу использовать (0 ... n) .map {}, но компилятор, похоже, не распознает map {}, если вы не используете параметр.
источник
forEach
если вам не нужно возвращаемое значение, и я уверен, что_ in
это обязательно/0xffffffff
для btwHaskell , 97 байт
Попробуйте онлайн!
Просто ваше основное преобразование Бокса-Мюллера в бесконечном списке случайных чисел.
источник
Python 3 , 118 байт
Попробуйте онлайн!
источник
SmileBASIC, 81 байт
Ну, теперь, когда я ответил на первый вопрос, я должен сделать все остальное ...
Генерация случайных чисел обходится дешево, но для заполнения ГСЧ используется самая длинная встроенная функция в языке
RANDOMIZE
.Может быть, есть какой-то способ оптимизировать формулу. Я не понимаю, как требуется использовать два вызова RNG.
источник