Соревнование
Напишите программу или функцию, которая не требует ввода и выводит вектор длины в теоретически однородном случайном направлении.
Это эквивалентно случайной точке на сфере, описываемой
в результате чего такое распределение
Выход
Три числа с плавающей точкой из теоретически однородного случайного распределения, для которого уравнение выполняется в пределах точности.
Вызов замечания
- Случайное распределение должно быть теоретически однородным . То есть, если генератор псевдослучайных чисел заменить истинным ГСЧ из действительных чисел, это приведет к равномерному случайному распределению точек на сфере.
- Генерирование трех случайных чисел из равномерного распределения и их нормализация недопустимы: будет смещение в сторону углов трехмерного пространства.
- Аналогично, создание двух случайных чисел из равномерного распределения и использование их в качестве сферических координат недопустимо: будет иметь место смещение к полюсам сферы.
- Надлежащее единообразие может быть достигнуто с помощью алгоритмов, включая, но не ограничиваясь:
- Генерация трех случайных чисел , и из нормального (гауссовского) распределения около и нормализация их.
- Генерация трех случайных чисел , и из равномерного распределения в диапазоне . Вычислить длину вектора с помощью . Затем, если , отбросим вектор и сгенерируем новый набор чисел. Иначе, если , нормализовать вектор и вернуть результат.
- Генерация двух случайных чисел и из равномерного распределения в диапазоне и преобразование их в сферические координаты, например, так: так что,имогут быть вычислены как
- Предоставьте в своем ответе краткое описание используемого вами алгоритма.
- Узнайте больше о выборе точек на MathWorld .
Примеры вывода
[ 0.72422852 -0.58643067 0.36275628]
[-0.79158628 -0.17595886 0.58517488]
[-0.16428481 -0.90804027 0.38532243]
[ 0.61238768 0.75123833 -0.24621596]
[-0.81111161 -0.46269121 0.35779156]
Основные пометки
- Это код-гольф , поэтому ответ, использующий наименьшее количество байтов на каждом языке, выигрывает.
- Применяются стандартные правила , правила ввода / вывода и лазейки .
- Пожалуйста, включите ссылку Try it Online или эквивалентную, чтобы продемонстрировать, как работает ваш код.
- Пожалуйста, мотивируйте ваш ответ объяснением вашего кода.
pi/6 ≈ 0.5236
произвести вывод. Это площадь сферы, вписанная в единичный кубОтветы:
Wolfram Language (Mathematica) , 20 байтов
Попробуйте онлайн!
Делает именно то, что говорит на жестяной банке.
источник
R , 23 байта
Попробуйте онлайн!
Генерирует 3 реализации распределенияN(0,1) и нормализует результирующий вектор.
Участок 1000 реализаций:
источник
Машинный код x86-64 -
63 62 5549 байтИспользует второй алгоритм, модифицированный. Возвращает вектор
[x, y, z, 0]
в формате xmm0.Объяснение:
Выдвигает значение для 1 и 2 ^ 31 как число с плавающей точкой в стек. Данные перекрываются из-за расширения знака, сохраняя несколько байтов.
vbroadcastss xmm1,dword ptr [rsp+5]
Загружает значение для 2 ^ 31 в 4 позиции xmm1.Генерирует случайное 32-разрядное целое число и загружает его в конец xmm0.
Создает случайное 32-разрядное целое число, преобразует его в число с плавающей точкой (со знаком) и делит на 2 ^ 31, чтобы получить числа от -1 до 1.
vdpps xmm2,xmm0,xmm0,7Fh
добавляет квадраты нижних 3 поплавков, используя сам точечный продукт, маскируя верхний поплавок. Это дает длинуСравнивает длину в квадрате с 1 и отклоняет значения, если она не равна 1. Если длина в квадрате равна единице, то длина также равна единице. Это означает, что вектор уже нормализован и сохраняет квадратный корень и делит.
Восстановите стек.
ret
возвращает значение в xmm0Попробуйте онлайн .
источник
aesenc
для создания 128 «случайных» бит просто прекрасно.Python 2 , 86 байт
Попробуйте онлайн!
Генерирует z-координату равномерно от -1 до 1. Затем координаты x и y выбираются равномерно по кругу радиуса
(1-z*z)**.5
.Может быть неочевидно, что сферическое распределение в коэффициенте равномерно по координате z (и так по каждой координате). Это нечто особенное для измерения 3. Посмотрите на это доказательство того, что площадь поверхности горизонтального среза сферы пропорциональна ее высоте. Хотя срезы около экватора имеют больший радиус, срезы около полюса имеют больший внутренний заголовок, и оказывается, что эти два эффекта точно отменяются.
Чтобы сгенерировать случайный угол на этом круге, мы поднимаем мнимую единицу
1j
до равномерно случайной степени между 0 и 4, что избавляет нас от необходимости использовать функции триггера, pi или e, для любой из которых потребуется импорт. Затем мы извлекаем реальную мнимую часть. Если мы можем вывести комплексное число для двух координат, последняя строка может быть простоprint a,z
.86 байт
Попробуйте онлайн!
Создает три нормали и масштабирует результат.
Python 2 с NumPy, 57 байтов
Попробуйте онлайн!
sum(a*a)**.5
короче чемlinalg.norm(a)
. Мы могли бы также сделатьdot(a,a)
для той же длины, что иsum(a*a)
. В Python 3 это можно сократить доa@a
использования оператора new@
.источник
z
из равномерного распределения оставить неизменным.z
, и исправил это на несколько байтов.Октава ,
40 3322 байтаМы выбираем форму стандартного нормального распределения 3d и нормализуем вектор:
Попробуйте онлайн!
источник
disp
:)Unity C # , 34 байта
Unity имеет встроенную функцию для случайных значений сфер, поэтому я решил опубликовать ее.
источник
f=>Random.onUnitSphere
f
Type; использованиеvar
только работает внутри метода иSystem.Func<Vector3>
дольше.f=>Random.onUnitSphere
это совершенно действительное представлениеf=>UnityEngine.Random.onUnitSphere
спасает васusing
MATL , 10 байт
Попробуйте онлайн!
объяснение
При этом используется первый подход, описанный в задаче.
источник
Рубин ,
34 5049 байтовПопробуйте онлайн!
Возвращает массив из 3 чисел
[z,y,x]
.x
иy
генерируются путем повышенияi
(квадратный корень из -1) до случайной степени между 0 и 4. Это комплексное число должно быть соответствующим образом масштабировано в соответствии соz
значением в соответствии с теоремой Пифагора:(x**2 + y**2) + z**2 = 1.
z
Координат (который генерируется первая) просто равномерно распределено число между -1 и 1. Хотя это и не сразу видно, дА / дг для среза через сферу постоянна (и равна периметру окружности того же радиуса, вся сфера.).Это, по-видимому, было обнаружено Архимедом, который описал его очень не в форме исчисления, и это известно как теорема Архимеда о шляпной коробке. Смотрите https://brilliant.org/wiki/surface-area-sphere/
Еще одна ссылка из комментариев на ответ xnor. Удивительно короткий URL, описывающий удивительно простую формулу: http://mathworld.wolfram.com/Zone.html
источник
[z, x+yi]
я оставлю это как есть, если вы не скажете, что все в порядке.z*z
вместоz**2
?z*z
. Я редактировал это сейчас. Другая вещь, которую я мог бы сделать, это заменитьrand*4
чем-то вродеz*99
илиx*9E9
(эффективно ограничивая возможные значения очень тонкой спиралью на сфере), но я думаю, что это снижает качество случайного.05AB1E ,
2322 байтаРеализует 2-й алгоритм.
Попробуйте онлайн или получите еще несколько случайных результатов .
Объяснение:
ПРИМЕЧАНИЕ: 05AB1E не имеет встроенной функции для получения случайного десятичного значения в диапазоне[ 0 , 1 ) , Вместо этого я создаю список с шагом0,00001 и выберите случайные значения из этого списка. Это приращение может быть изменено на0,000000001 путем изменения
5
к9
в коде (хотя это стало бы довольно медленно ..).источник
TI-BASIC, 15 байтов *
Используя алгоритм «сгенерируйте 3 нормально распределенных значения и нормализуйте этот вектор».
Завершение программы с выражением автоматически печатает результат на главном экране после завершения программы, так что результат фактически отображается, а не просто генерируется и попадает в черный цвет.
*:
randNorm(
это двухбайтовый токен , остальные - однобайтовые токены . Я посчитал начальный (неизбежный):
, без этого это было бы 14 байтов. Сохраненный как программа с однобуквенным именем, он занимает 24 байта памяти, что включает 9 байтов служебной информации файловой системы.источник
JavaScript (ES7),
77 7675 байтРеализует 3- й алгоритм, используягрех( ϕ ) = грех( потому что- 1( з) ) = 1 - z2-----√ ,
Попробуйте онлайн!
комментарии
JavaScript (ES6), 79 байт
Реализует 2- й алгоритм.
Попробуйте онлайн!
комментарии
источник
Обработка 26 байтов
Полная программа
Это реализация https://github.com/processing/processing/blob/master/core/src/processing/core/PVector.java
источник
Python 2 , 86 байт
Попробуйте онлайн!
Реализует первый алгоритм.
Python 2 ,
107103 байтаПопробуйте онлайн!
Реализует второй алгоритм.
источник
Haskell ,
125123119118 байтПопробуйте онлайн!
Делает три униформы случайных и бракованных выборок.
источник
JavaScript, 95 байт
Вам
ненужно не вводитьa
.источник
Юлия 1,0 , 24 байта
Попробуйте онлайн!
Рисует вектор из 3 значений, взятый из нормального распределения около 0 со стандартным отклонением 1. Затем просто нормализует их.
источник
randn()
из нескольких быстрых тестов, похоже, не привязан к требуемому диапазону. Кроме того, это не включает проверкуhypot()
возврата значения>1
, которая должна быть отклонена.randn
имитирует стандартное нормальное распределение, а не равномерное (0,1), поэтому этот подход идентичен подходу R.[-1,1)
то делите их на гипотенуза, которая будет>1
, компенсирует это? Это заставляет меня задуматься, нужна ли троичная форма в моем решении ...MathGolf ,
211918 байтРеализация 2-го алгоритма.
Попробуйте онлайн или посмотрите несколько выходов одновременно .
Объяснение:
источник
Java 8 ( модифицированный 3-й алгоритм @Arnauld ),
131126119111109 байтПорт из @Arnauld 's JavaScript answer , так что обязательно проголосуйте за него!
-2 байта благодаря @ OlivierGrégoire .
Это реализовано как:
Попробуйте онлайн.
Предыдущая реализация третьего алгоритма (
131126119 байт):Реализуется как:
Попробуйте онлайн.
Объяснение:
Java 8 (2-й алгоритм),
153143 байтаПопробуйте онлайн.
2-й алгоритм:
источник
sqrt(1-k*k)
фактически экономит больше байтов в Java, чем в JS. :)M.sin
, 1xM.cos
и 1xM.acos
ваш подход использует 2xM.sin
и 1xM.sqrt
, из которых в основном поступают дополнительные сохраненные байты. :)double[]
чтобы не изменять счетчик байтов.)Japt , 20 байт
Порт Арнаулда по реализации 2-го алгоритма.
Попробуй это
источник
Pyth , 24 байта
Попробуйте онлайн!
Использует алгоритм № 2
источник
OCaml ,
1109995 байтовРЕДАКТИРОВАТЬ: сбрил некоторые байты, вставляяя а также J , заменяя первое
let ... in
на afun
, и используя ассоциативность операторов, чтобы избежать некоторых слов()
.Попробуйте онлайн
Оригинальное решение:
Сначала я определяю:
Random.float
Функция OCaml включает в себя границы. Затем,Это очень похоже на реализацию третьего примера (сϕ = p а также θ = т ) - кроме того, что я выбираю я а также J в больших интервалах, чтобы избежать умножения (с 2) позже.
источник
0
и1
непосредственно. Это неверно, как показано в примечаниях к вызовам 3 и 4, так как в итоге вы получаете уклон к полюсам сферы. Вы можете исправить это, применив метод, показанный в примечании 4.