Випадкова точка на кулі


31

Змагання

Напишіть програму або функцію, яка не займає введення і виводить вектор довжиною у теоретично рівномірному випадковому напрямку.1

Це еквівалентно випадковій точці на сфері, описаній

x2+y2+z2=1

в результаті такого розподілу

Випадковий розподіл точок на кулі з радіусом 1.

Вихід

Три плавці з теоретично рівномірного випадкового розподілу, для якого рівняння справедливо для меж точності.x2+y2+z2=1

Зауваження виклику

  • Випадковий розподіл повинен бути теоретично рівномірним . Тобто, якби генератор псевдовипадкових чисел був замінений справжнім RNG від реальних чисел, це призвело б до рівномірного випадкового розподілу точок по сфері.
  • Генерування трьох випадкових чисел з рівномірного розподілу та їх нормалізація недійсні: з'явиться ухил у бік кутів тривимірного простору.
  • Аналогічно, генерування двох випадкових чисел з рівномірного розподілу та використання їх як сферичних координат є недійсним: відбудеться ухил до полюсів сфери.
  • Належної рівномірності можна досягти алгоритмами, включаючи, але не обмежуючись ними:
    • Утворіть три випадкових числа , і з нормального (гауссового) розподілу навколо і нормалізуйте їх. xyz00
    • Утворіть три випадкові числа , і з рівномірного розподілу в діапазоні . Обчисліть довжину вектора по . Тоді, якщо , відкиньте вектор і генеруйте новий набір чисел. В іншому випадку, якщо , нормалізуйте вектор і поверніть результат. xyz( - 1 , 1 ) l = (1,1)l=x2+y2+z2l>1l1
    • Згенеруйте два випадкових числа та з рівномірного розподілу в діапазоні та перетворіть їх у сферичні координати, наприклад: так що , і можна обчислити черезij( 0 , 1 ) θ(0,1)
      θ=2×π×iϕ=cos1(2×j1)
      xyz
      x=cos(θ)×sin(ϕ)y=sin(θ)×sin(ϕ)z=cos(ϕ)
  • Надайте у своїй відповіді короткий опис алгоритму, який ви використовуєте.
  • Детальніше про підбір точок сфери читайте на 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]

Загальні зауваження


Чи добре вибирати 3 рівномірно рівномірно в [-1, 1], а потім відхиляти їх (і повторювати), якщо сума їх квадратів не дорівнює 1?
Grimmy

6
@Grimy Мені подобається ця лазівка. Ні, це не дозволено, оскільки теоретично є нульовий шанс будь-якого виходу.
Jitse

Чи не пропозиція @ Грімі схожа на згаданий вами приклад другого прикладу? Це рішення також теоретично має нульовий шанс отримати будь-яку продукцію
Сасват Падхі

2
@SaswatPadhi Ні, це має шанс pi/6 ≈ 0.5236отримати вихід. Це область сфери, вписана в куб одиничної площі
Луїс Мендо

1
@LuisMendo Я бачу, правда. У тому випадку, як ви вже згадували, вірогідність становить ~ 0,5. Для пропозиції Гримі це ~ 0.
Сасват Падхі

Відповіді:



24

R , 23 байти

x=rnorm(3)
x/(x%*%x)^.5

Спробуйте в Інтернеті!

Породжує 3 реалізації розподілу і нормалізує отриманий вектор.N(0,1)

Сюжет 1000 реалізацій:

введіть тут опис зображення


2
Чи можете ви обґрунтувати звичайну розподілену 3 вісь, що призведе до рівномірного розподілу по сфері? (Я цього не бачу)
Джефрі підтримує Моніку

4
X,YN(0,1)fX(x)=Ke12x2fY(y)=Ke12y2fXY(x,y)=K2e12(x2+y2)=fZ(z)=K2e12z2z zz=(x,y)zz

1
Отже, нормальне розподіл дає нам рівномірно розподілені точки навколо кола, а ділення на величину забезпечує точки, що лежать на колі
Джузеппе,

23

x86-64 Код машини - 63 62 55 49 байт

6A 4F                push        4Fh  
68 00 00 80 3F       push        3F800000h  
C4 E2 79 18 4C 24 05 vbroadcastss xmm1,dword ptr [rsp+5]  
rand:
0F C7 F0             rdrand      eax  
73 FB                jnc         rand  
66 0F 6E C0          movd        xmm0,eax  
greaterThanOne:
66 0F 38 DC C0       aesenc      xmm0,xmm0  
0F 5B C0             cvtdq2ps    xmm0,xmm0  
0F 5E C1             divps       xmm0,xmm1  
C4 E3 79 40 D0 7F    vdpps       xmm2,xmm0,xmm0,7Fh  
0F 2F 14 24          comiss      xmm2,dword ptr [rsp]  
75 E9                jne         greaterThanOne
58                   pop         rax  
58                   pop         rax  
C3                   ret  

Використовується другий алгоритм, модифікований. Повертає вектор [x, y, z, 0]у xmm0.

Пояснення:

push 4Fh
push 3f800000h

Висуває значення для 1 і 2 ^ 31 як поплавок на стек. Дані перекриваються через розширення знаків, економлячи кілька байт.

vbroadcastss xmm1,dword ptr [rsp+5] Завантажує значення для 2 ^ 31 у 4 позиції xmm1.

rdrand      eax  
jnc         rand  
movd        xmm0,eax

Створює випадкове 32-бітове ціле число і завантажує його на дно xmm0.

aesenc      xmm0,xmm0  
cvtdq2ps    xmm0,xmm0  
divps       xmm0,xmm1 

Створює випадкове 32-бітове ціле число, перетворює його на плаваюче (підписане) і ділить на 2 ^ 31, щоб отримати числа між -1 і 1.

vdpps xmm2,xmm0,xmm0,7Fhдодає квадрати нижнього 3 поплавця, використовуючи крапковий добуток сам по собі, маскуючи верхній поплавок. Це дає довжину

comiss      xmm2,dword ptr [rsp]  
jne          rand+9h (07FF7A1DE1C9Eh)

Порівняє довжину в квадраті з 1 і відкидає значення, якщо вона не дорівнює 1. Якщо довжина квадрата одна, то довжина також одна. Це означає, що вектор вже нормалізований і зберігає квадратний корінь і ділиться.

pop         rax  
pop         rax 

Відновіть стек.

ret повертає значення в xmm0

Спробуйте в Інтернеті .


7
+1 Використовувати aesencдля створення 128 "випадкових" бітів просто прекрасно.
DocMax

13

Python 2 , 86 байт

from random import*;R=random
z=R()*2-1
a=(1-z*z)**.5*1j**(4*R())
print a.real,a.imag,z

Спробуйте в Інтернеті!

Створює z-координату рівномірно від -1 до 1. Тоді координати x і y відбирають вибірково по колу радіусу (1-z*z)**.5.

Можливо, не очевидно, що сферичний розподіл є факторним рівномірним по координаті z (і так над кожною координатою). Це щось особливе для розміру 3. Дивіться цей доказ того, що площа поверхні горизонтального зрізу кулі пропорційна його висоті. Хоча зрізи біля екватора мають більший радіус, скибочки біля полюса мають титул всередину більше, і, виявляється, ці два ефекти точно скасовуються.

Щоб генерувати випадковий кут на цьому колі, ми піднімаємо уявну одиницю 1jдо рівномірно випадкової потужності між 0 і 4, що рятує нас від необхідності функцій триггера, pi або e, будь-який з яких потребує імпорту. Потім ми витягуємо справжню уявну частину. Якщо ми можемо вивести складне число для двох координат, останній рядок може бути просто print a,z.


86 байт

from random import*
a,b,c=map(gauss,[0]*3,[1]*3)
R=(a*a+b*b+c*c)**.5
print a/R,b/R,c/R

Спробуйте в Інтернеті!

Створює три нормалі та масштабує результат.


Python 2 з numpy, 57 байт

from numpy import*
a=random.randn(3)
print a/sum(a*a)**.5

Спробуйте в Інтернеті!

sum(a*a)**.5коротше, ніж linalg.norm(a). Ми також могли б зробити dot(a,a)таку ж довжину, як і sum(a*a). У Python 3 це може бути скорочено до a@aвикористання нового оператора @.


1
Мені подобається ваш перший підхід. У мене виникають проблеми з розумінням того, як уникнути ухилу в бік екватора, якщо zпри рівномірному розподілі залишити без змін.
Jitse

2
@Jitse Сферичний розподіл у факторному рівномірному для кожної координати. Це щось особливе для розміру 3. Дивіться, наприклад, цей доказ того, що площа поверхні шматочка кулі пропорційна його висоті. Що стосується інтуїції, що це упереджено до екватора, зауважте, що хоча зрізи біля екватора мають більший радіус, осередки біля полюса мають титул всередину більше, що дає більше площі, і, виявляється, ці два ефекти точно скасовуються.
xnor

Дуже хороша! Дякуємо за роз’яснення та довідку.
Jitse

@Jitse Спасибі, я додав його до тіла. Хоча я зрозумів, що беру лише позитивний вибірки z, і зафіксував це на кілька байт.
xnor

1
@Jitse Дійсно, площа поверхні кулі дорівнює площі бічної поверхні додаючого циліндра!
Ніл

13

Октава , 40 33 22 байт

Ми робимо вибірку з 3д стандартного нормального розподілу і нормалізуємо вектор:

(x=randn(1,3))/norm(x)

Спробуйте в Інтернеті!


Тільки для Octave (тобто не MATLAB), ви можете зберегти байт за допомогою цього
Том Карпентер,

1
@TomCarpenter Дякую! У цьому випадку, оскільки це лише один вираз, ми можемо навіть опустити disp:)
недолік

10

Єдність C # , 34 байти

f=>UnityEngine.Random.onUnitSphere

У Unity є вбудована для одиничних сфера випадкова величина, тому я подумав, що опублікую його.


Гарне використання вбудованого +1, ви можете просто надіслати функцію трохи коротшеf=>Random.onUnitSphere
LiefdeWen

@LiefdeWen Я знав про лямбда, я просто не був впевнений, чи цього достатньо (з точки зору дійсності на Code Golf), оскільки це не декларує fтип; використовуючи varлише роботи всередині методу і System.Func<Vector3>було довше.
Draco18s

1
У кодегольфі повернення функції ідеально, і вам не доведеться рахувати декларацію або означає, що ви можете робити підлі речі з динамічними параметрами. Ви також не рахуєте останньої напівкрапки. Однак ви рахуєте всі доданки, які ви додаєте. тому ваш байт повинен включати в себе використання. Але f=>Random.onUnitSphereце цілком коректне подання
LiefdeWen

@LiefdeWen Так, я просто не був впевнений, як обробляється декларація, і не дуже відчував "пошук мета".
Draco18s

f=>UnityEngine.Random.onUnitSphereрятує васusing
Орація


6

Рубі , 34 50 49 байт

->{[z=rand*2-1]+((1-z*z)**0.5*1i**(rand*4)).rect}

Спробуйте в Інтернеті!

Повертає масив з 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


@Jitse Я забув масштабувати х і у при високих значеннях z. Ефективно точки визначали циліндр. Це зараз виправлено, але це коштувало багато байтів! Я міг би зберегти декілька, якщо вихід може бути виражений складним числом, [z, x+yi]я залишу його таким, як є, якщо ви не скажете, що це нормально.
Рівень р. Св.

Виглядає добре! Мені дуже подобається такий підхід. Для узгодженості необхідний вихід три поплавці, тому я пропоную залишити його так.
Jitse

Чому б не використовувати z*zзамість z**2?
Значення чорнила

@ValueInk так, дякую, я зрозумів, що пропустив це z*z. Я редагував це зараз. Інше, що я міг би зробити, це замінити rand*4щось на кшталт z*99або x*9E9(ефективно обмежуючи можливі значення дуже тонкою спіраллю на сфері), але я думаю, що це знижує якість випадкового.
Рівень р. Св.

4

05AB1E , 23 22 байти

[тε5°x<Ýs/<Ω}DnOtDî#}/

Реалізує 2-й алгоритм.

Спробуйте в Інтернеті або отримайте ще кілька випадкових результатів .

Пояснення:

ПРИМІТКА: 05AB1E не має вбудованого для отримання випадкового десяткового значення в діапазоні . Натомість я створюю список з кроком і вибираю з цього списку випадкові значення. Це збільшення може бути змінено на шляхом зміни до в коді (хоча це стало б досить повільно ..).[0,1)0.000010.00000000159

[            # Start an infinite loop:
 тε          #  Push 100, and map (basically, create a list with 3 values):
   5°        #   Push 100,000 (10**5)
     x       #   Double it to 200,000 (without popping)
      <      #   Decrease it by 1 to 199,999
       Ý     #   Create a list in the range [0, 199,999]
        s/   #   Swap to get 100,000 again, and divide each value in the list by this
          <  #   And then decrease by 1 to change the range [0,2) to [-1,1)
           Ω #   And pop and push a random value from this list
  }          #  After the map, we have our three random values
   D         #   Duplicate this list
    n        #   Square each inner value
     O       #   Take the sum of these squares
      t      #   Take the square-root of that
       D     #   Duplicate that as well
        î    #   Ceil it, and if it's now exactly 1:
         #   #    Stop the infinite loop
}/           # After the infinite loop: normalize by dividing
             # (after which the result is output implicitly)

1
Використання однаково справедливо, як . Єдиним критерієм є те, що . Ви можете також добре приймати вектори з якщо це збереже будь-які байти. Будь-яке значення менше або рівне знімає зміщення. l 1 l x 0 < x 1 l < 0,5 1l<1l1lx0<x1l<0.51
Jitse

@Jitse Гаразд, реалізував нормалізацію в моїх відповідях Java та 05AB1E. Сподіваюся, зараз все правильно.
Кевін Круїссен

@Jitse Фактично збережено байт, перевіривши як , замість . Але дякую за уточнення, що лише - це вимога, а на немає суворої вимоги , якщо це . v = = 1 v < 1 0 < x 1 l 1v1v==1v<10<x1l1
Кевін Круїссен

4

TI-BASIC, 15 байт *

:randNorm(0,1,3
:Ans/√(sum(Ans²

Використовуючи алгоритм "генерувати 3 нормально розподілених значення та нормалізувати цей вектор".

Закінчення програми з виразом автоматично друкує результат на домашньому екрані після закінчення програми, тому результат насправді відображається, а не просто генерується і не проводиться в чорному режимі.

*: randNorm(- двобайтовий маркер , решта - однобайтові лексеми . Я порахував початковий (неминучий) :, без цього було б 14 байт. Збережена як програма з однобуквеною назвою, вона займає 24 байти пам'яті, що включає 9 байт накладних даних файлової системи.


3

JavaScript (ES7),  77 76  75 байт

Реалізує третій алгоритм, використовуючи .sin(ϕ)=sin(cos1(z))=1z2

with(Math)f=_=>[z=2*(r=random)()-1,cos(t=2*PI*r(q=(1-z*z)**.5))*q,sin(t)*q]

Спробуйте в Інтернеті!

Прокоментував

with(Math)                       // use Math
f = _ =>                         //
  [ z = 2 * (r = random)() - 1,  // z = 2 * j - 1
    cos(                         //
      t =                        // θ =
        2 * PI *                 //   2 * π * i
        r(q = (1 - z * z) ** .5) // q = sin(ɸ) = sin(arccos(z)) = √(1 - z²)
                                 // NB: it is safe to compute q here because
                                 //     Math.random ignores its parameter(s)
    ) * q,                       // x = cos(θ) * sin(ɸ)
    sin(t) * q                   // y = sin(θ) * sin(ɸ)
  ]                              //

JavaScript (ES6), 79 байт

Реалізує 2 - й алгоритм.

f=_=>(n=Math.hypot(...v=[0,0,0].map(_=>Math.random()*2-1)))>1?f():v.map(x=>x/n)

Спробуйте в Інтернеті!

Прокоментував

f = _ =>                         // f is a recursive function taking no parameter
  ( n = Math.hypot(...           // n is the Euclidean norm of
      v =                        // the vector v consisting of:
        [0, 0, 0].map(_ =>       //
          Math.random() * 2 - 1  //   3 uniform random values in [-1, 1]
        )                        //
  )) > 1 ?                       // if n is greater than 1:
    f()                          //   try again until it's not
  :                              // else:
    v.map(x => x / n)            //   return the normalized vector

3

Обробка 26 байт

Повна програма

print(PVector.random3D());

Це реалізація https://github.com/processing/processing/blob/master/core/src/processing/core/PVector.java

  static public PVector random3D(PVector target, PApplet parent) {
    float angle;
    float vz;
    if (parent == null) {
      angle = (float) (Math.random()*Math.PI*2);
      vz    = (float) (Math.random()*2-1);
    } else {
      angle = parent.random(PConstants.TWO_PI);
      vz    = parent.random(-1,1);
    }
    float vx = (float) (Math.sqrt(1-vz*vz)*Math.cos(angle));
    float vy = (float) (Math.sqrt(1-vz*vz)*Math.sin(angle));
    if (target == null) {
      target = new PVector(vx, vy, vz);
      //target.normalize(); // Should be unnecessary
    } else {
      target.set(vx,vy,vz);
    }
    return target;
  }

2
Ви можете уточнити, що реалізація не є частиною вашого байтового числа. Я пропустив це в першому читанні, потім зробив подвійний знімок.
Рівень р. Св.

Мені подобається , що використання реалізації по суті такий же підхід , як і я, хоча
River Level St

2

Python 2 , 86 байт

from random import*
x,y,z=map(gauss,[0]*3,[1]*3);l=(x*x+y*y+z*z)**.5
print x/l,y/l,z/l

Спробуйте в Інтернеті!

Реалізує перший алгоритм.


Python 2 , 107 103 байт

from random import*
l=2
while l>1:x,y,z=map(uniform,[-1]*3,[1]*3);l=(x*x+y*y+z*z)**.5
print x/l,y/l,z/l

Спробуйте в Інтернеті!

Реалізує другий алгоритм.


2
@RobinRyder Ця реалізація відхиляє вектори з початковою довжиною> 1, що діє, як зазначено в виклику.
Jitse

@Jitse Правильно, вибач. Я неправильно прочитав код.
Робін Райдер

2

Haskell , 125 123 119 118 байт

import System.Random
f=mapM(\_->randomRIO(-1,1))"lol">>= \a->last$f:[pure$(/n)<$>a|n<-[sqrt.sum$map(^2)a::Double],n<1]

Спробуйте в Інтернеті!

Чи три уніформи та вибірки відхилення.


Схоже, що ваші викупні кошти виходять з розподілу (0,1) замість (-1,1), так що покрита лише 1/8 сфери.
Jitse

@Jitse gotcha, дякую, що помітили.
Ангс

2

JavaScript, 95 байт

f=(a=[x,y,z]=[0,0,0].map(e=>Math.random()*2-1))=>(s=Math.sqrt(x*x+y*y+z*z))>1?f():a.map(e=>e/s)

Вам не потрібно не вводити a.


Нічого собі, я цілком пропустив це. Виправлено.
Наруйоко

2

Джулія 1,0 , 24 байти

x=randn(3)
x/hypot(x...)

Спробуйте в Інтернеті!

Намалює вектор з 3 значень, виведених із нормального розподілу навколо 0 зі стандартним відхиленням 1. Потім просто їх нормалізує.


randn(), через пару швидких тестів, схоже, не прив’язаний до необхідного діапазону. Крім того, це не включає чек на hypot()повернення значення >1, яке слід відхилити.
Кудлатий

3
@Shaggy, здавалося б, randnімітує стандартний нормальний розподіл, а не рівномірний (0,1), тому такий підхід ідентичний R.
Джузеппе

@Giuseppe Так!
користувач3263164

@Giuseppe, я думаю, що я, можливо, не маю належного розуміння щодо математики, яка стоїть перед цим викликом, але, якщо я вас правильно зрозумів, ти кажеш, що якщо будь-який з плавців знаходиться поза межами, [-1,1)то розділиш їх на гіпотенуза, яка буде >1, компенсує це? Це змушує мене замислитись, чи потрібен потрійник у моєму рішенні ...
Shaggy

@Шаггі ні, нормальний / гауссовий розподіл має деякі властивості (зокрема, обертальну інваріантність), яких не має уніформа, дивіться цей коментар , наприклад
Джузеппе

2

MathGolf , 21 19 18 байт

{╘3Ƀ∞(ß_²Σ√_1>}▲/

Реалізація 2-го алгоритму.

Спробуйте в Інтернеті або подивіться ще кілька результатів одночасно .

Пояснення:

{              }▲   # Do-while true by popping the value:
                   #  Discard everything on the stack to clean up previous iterations
  3É                #  Loop 3 times, executing the following three operations:
    ƒ               #   Push a random value in the range [0,1]
                   #   Double it to make the range [0,2]
      (             #   Decrease it by 1 to make the range [-1,1]
       ß            #  Wrap these three values into a list
        _           #  Duplicate the list of random values
         ²          #  Square each value in the list
          Σ         #  Sum them
                   #  And take the square-root of that
            _       #  Duplicate it as well
             1>     #  And check if it's larger than 1
                 /  # After the do-while, divide to normalize
                    # (after which the entire stack joined together is output implicitly,
                    #  which is why we need the `╘` to cleanup after every iteration)

2

Java 8 ( модифікований 3-й алгоритм @Arnauld ), 131 126 119 111 109 байт

v->{double k=2*M.random()-1,t=M.sqrt(1-k*k),r[]={k,M.cos(k=2*M.PI*M.random())*t,M.sin(k)*t};return r;}

Порт @Arnauld у відповідь на JavaScript , тому не забудьте підтримати його!
-2 байти завдяки @ OlivierGrégoire .

Це реалізується як:

k=N[1,1)
t=1k2
u=2π×(N[0,1))
x,y,z={k,cos(u)×t,sin(u)×t}

Спробуйте в Інтернеті.

Попередня реалізація 3-го алгоритму ( 131 126 119 байт):

Math M;v->{double k=2*M.random()-1,t=2*M.PI*M.random();return k+","+M.cos(t)*M.sin(k=M.acos(k))+","+M.sin(t)*M.sin(k);}

Реалізовано як:

k=N[1,1)
t=2π×(N[0,1))
x,y,z={k,cos(t)×sin(arccos(k)),sin(t)×sin(arccos(k))}

Спробуйте в Інтернеті.

Пояснення:

Math M;                         // Math on class-level to use for static calls to save bytes
v->{                            // Method with empty unused parameter & double-array return
  double k=2*M.random()-1,      //  Get a random value in the range [-1,1)
         t=M.sqrt(1-k*k),       //  Calculate the square-root of 1-k^2
    r[]={                       //  Create the result-array, containing:
         k,                     //   X: the random value `k`
         M.cos(k=2*M.PI         //   Y: first change `k` to TAU (2*PI)
                     *M.random()//       multiplied by a random [0,1) value
                )               //      Take the cosine of that
                 *t,            //      and multiply it by `t`
         M.sin(k)               //   Z: Also take the sine of the new `k` (TAU * random)
                  *t};          //      And multiply it by `t` as well
  return r;}                    //  Return this array as result

Java 8 (2-й алгоритм), 153 143 байт

v->{double x=2,y=2,z=2,l;for(;(l=Math.sqrt(x*x+y*y+z*z))>1;y=m(),z=m())x=m();return x/l+","+y/l+","+z/l;};double m(){return Math.random()*2-1;}

Спробуйте в Інтернеті.

2-й алгоритм:

v->{                              // Method with empty unused parameter & String return-type
  double x=2,y=2,z=2,l;           //  Start results a,b,c all at 2
  for(;(l=Math.sqrt(x*x+y*y+z*z)) //  Loop as long as the hypotenuse of x,y,z
       >1;                        //  is larger than 1
    y=m(),z=m())x=m();            //   Calculate a new x, y, and z
  return x/l+","+y/l+","+z/l;}    //  And return the normalized x,y,z as result
double m(){                       // Separated method to reduce bytes, which will:
  return Math.random()*2-1;}      //  Return a random value in the range [-1,1)

Використання sqrt(1-k*k)фактично економить більше байтів на Java, ніж це в JS. :)
Арнольд

@Arnauld Так. Замість 3x M.sin, 1x M.cosта 1x M.acos, ваш підхід використовує 2x M.sinта 1x M.sqrt, звідки в основному беруться додаткові збережені байти. :)
Кевін Круїссен

108 байт Використовує модифікований 2-й алгоритм, де я дозволяю лише значення, де s == 1 (замість s <= 1, а потім нормалізується). Іноді це дає відповідь, але, як правило, не через час очікування. Редагувати: На жаль, я забув Math.sqrt результат
Олів'є

Насправді, ні, не потрібно sqrt, тому що sqrt (1) == 1. Тож я стою з моєю пропозицією про гольф.
Олів'є Грегоар

1
109 байт (ви можете використовувати рядок виводу замість того double[], що не змінює кількість байтів)
Олів'є Грегоар


1

Pyth , 24 байти

W<1Ks^R2JmtO2.0 3;cR@K2J

Спробуйте в Інтернеті!

Використовує алгоритм №2

W                         # while 
 <1                       #   1 < 
   Ks                     #       K := sum(
     ^R2                  #               map(lambda x:x**2,
        Jm      3         #                    J := map(                            , range(3))
          tO2.0           #                             lambda x: random(0, 2.0) - 1           )):
                 ;        #   pass
                   R   J  # [return] map(lambda x:            , J)
                  c @K2   #                        x / sqrt(K)

1

OCaml , 110 99 95 байт

(fun f a c s->let t,p=f 4.*.a 0.,a(f 2.-.1.)in[c t*.s p;s t*.s p;c p])Random.float acos cos sin

ijlet ... infun()

Спробуйте в Інтернеті


Оригінальне рішення:

Random.(let a,c,s,i,j=acos,cos,sin,float 4.,float 2. in let t,p=i*.(a 0.),a (j-.1.) in[c t*.s p;s t*.s p;c p])

Спочатку я визначаю:

a=arccos,  c=cos,  s=siniunif(0,4),  junif(0,2)

Random.floatФункція OCaml включає межі. Потім,

t=ia(0)=iπ2,  p=a(j1)

ϕ=pθ=tij


1
Я не зовсім знайома з цією мовою, але, схоже, ви використовуєте випадкові плавки між 0та 1безпосередньо як сферичні координати. Це невірно, як показано в зауваженнях 3 та 4 виклику, оскільки ви закінчуєте упередження до полюсів сфери. Ви можете виправити це, застосувавши метод, показаний у
примітці

Дякую! Повністю пропустив це. Виправлено помилку та оновив мою відповідь
Saswat Padhi

1
Виглядає добре! Дуже приємна перша відповідь!
Jitse

Дякую :) Мені вдалося зменшити його до нижче 100 байт!
Сасват Падхі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.