Wyzwanie
Napisz program lub funkcję, która nie pobiera danych wejściowych i wysyła wektor o długości w teoretycznie jednorodnym losowym kierunku.
Jest to równoważne losowemu punktowi na kuli opisanemu przez
powodując taką dystrybucję
Wydajność
Trzy zmiennoprzecinkowe z teoretycznie jednorodnego rozkładu losowego, dla którego równanie jest zgodne z granicami dokładności.
Uwagi na temat wyzwania
- Rozkład losowy musi być teoretycznie jednolity . Oznacza to, że gdyby generator liczb pseudolosowych został zastąpiony prawdziwym RNG z liczb rzeczywistych , spowodowałoby to jednolity losowy rozkład punktów na kuli.
- Generowanie trzech liczb losowych z jednolitego rozkładu i ich normalizacja jest nieprawidłowe: nastąpi odchylenie w kierunku narożników przestrzeni trójwymiarowej.
- Podobnie, generowanie dwóch liczb losowych z równomiernego rozkładu i stosowanie ich jako współrzędnych sferycznych jest nieprawidłowe: nastąpi odchylenie w kierunku biegunów kuli.
- Właściwą jednorodność można osiągnąć za pomocą algorytmów, w tym między innymi:
- Generowania trzech liczb losowych , i z pomocą normalnego (Gaussa) rozkład wokół i normalizować je. 0
- Generowania trzech liczb losowych, , i z równomiernym rozkładem w zakresie . Oblicz długość wektora o . Następnie, jeśli , odrzuć wektor i wygeneruj nowy zestaw liczb. W przeciwnym razie, jeśli , znormalizuj wektor i zwróć wynik. ( - 1 , 1 ) l = √
- Generowanie dwóch liczb losowych i z równomiernym rozkładem w przedziale i przekształcają je na sferyczne współrzędnych tak: , aby , i można było obliczyć za pomocą( 0 , 1 ) θ
- Podaj w swojej odpowiedzi krótki opis używanego algorytmu.
- Przeczytaj więcej na temat wybierania punktów kuli na MathWorld .
Przykłady wyników
[ 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]
Uwagi ogólne
- To jest golf golfowy , więc wygrywa odpowiedź wykorzystująca najmniej bajtów w każdym języku.
- Obowiązują standardowe reguły , reguły we / wy i reguły luk .
- Dołącz link Wypróbuj online lub równoważny, aby wykazać, że Twój kod działa.
- Motywuj swoją odpowiedź wyjaśnieniem swojego kodu.
pi/6 ≈ 0.5236
wyprodukować wyjście. Jest to obszar kuli wpisany w sześcian obszaru jednostkowegoOdpowiedzi:
Wolfram Language (Mathematica) , 20 bajtów
Wypróbuj online!
Robi dokładnie to, co jest napisane na puszce.
źródło
R , 23 bajty
Wypróbuj online!
Generuje 3 realizacje rozkładuN(0,1) i normalizuje uzyskany wektor.
Działka z 1000 realizacji:
źródło
x86-64 Kod maszynowy -
63 62 5549 bajtówUżywa zmodyfikowanego drugiego algorytmu. Zwraca wektor
[x, y, z, 0]
w xmm0.Wyjaśnienie:
Przesuwa wartość 1 i 2 ^ 31 jako liczbę zmiennoprzecinkową do stosu. Dane nakładają się z powodu rozszerzenia znaku, co pozwala zaoszczędzić kilka bajtów.
vbroadcastss xmm1,dword ptr [rsp+5]
Ładuje wartość 2 ^ 31 w 4 pozycjach xmm1.Generuje losową 32-bitową liczbę całkowitą i ładuje ją do dolnej części xmm0.
Generuje losową 32-bitową liczbę całkowitą, zamień ją na zmiennoprzecinkową (podpisaną) i podziel przez 2 ^ 31, aby uzyskać liczby od -1 do 1.
vdpps xmm2,xmm0,xmm0,7Fh
dodaje kwadraty dolnych 3 pływaków, używając samego produktu kropkowego, maskując górny pływak. To daje długośćPorównuje długość do kwadratu z 1 i odrzuca wartości, jeśli nie jest równa 1. Jeśli długość do kwadratu wynosi jeden, to długość jest również równa. Oznacza to, że wektor jest już znormalizowany i zapisuje pierwiastek kwadratowy i dzieli.
Przywróć stos.
ret
zwraca wartość w xmm0Wypróbuj online .
źródło
aesenc
do tworzenia 128 „losowych” bitów jest po prostu piękne.Python 2 , 86 bajtów
Wypróbuj online!
Generuje współrzędną z równomiernie od -1 do 1. Następnie współrzędne xiy są próbkowane równomiernie na okręgu o promieniu
(1-z*z)**.5
.Może nie być oczywiste, że rozkład sferyczny jest równomierny w stosunku do współrzędnej z (i tak w przypadku każdej współrzędnej). Jest to coś specjalnego dla wymiaru 3. Zobacz ten dowód, że pole powierzchni poziomego wycinka kuli jest proporcjonalne do jego wysokości. Chociaż plastry w pobliżu równika mają większy promień, plastry w pobliżu bieguna są bardziej skierowane do wewnątrz i okazuje się, że te dwa efekty dokładnie się anulują.
Aby wygenerować losowy kąt na tym okręgu, podnosimy wyimaginowaną jednostkę
1j
do równomiernie losowej mocy od 0 do 4, co oszczędza nam konieczności korzystania z funkcji wyzwalania, pi lub e, z których każda wymagałaby importu. Następnie wydobywamy prawdziwą wyimaginowaną część. Jeśli możemy wyprowadzić liczbę zespoloną dla dwóch współrzędnych, ostatnia linia może po prostu byćprint a,z
.86 bajtów
Wypróbuj online!
Generuje trzy normalne i skaluje wynik.
Python 2 z numpy, 57 bajtów
Wypróbuj online!
sum(a*a)**.5
jest krótszy niżlinalg.norm(a)
. Możemy również zrobićdot(a,a)
dla tej samej długości cosum(a*a)
. W Pythonie 3 można to skrócić doa@a
korzystania z nowego operatora@
.źródło
z
z jednolitego rozkładu pozostanie niezmodyfikowany.z
i naprawiłem to na kilka bajtów.Oktawa ,
40 3322 bajtówPróbkujemy z 3d standardowego rozkładu normalnego i normalizujemy wektor:
Wypróbuj online!
źródło
disp
:)Unity C # , 34 bajty
Unity ma wbudowane losowe wartości kuli jednostkowej, więc pomyślałem, że to opublikuję.
źródło
f=>Random.onUnitSphere
f
typu; używanievar
działa tylko wewnątrz metody iSystem.Func<Vector3>
było dłuższe.f=>Random.onUnitSphere
jest to całkowicie poprawne zgłoszenief=>UnityEngine.Random.onUnitSphere
ratuje ciusing
MATL , 10 bajtów
Wypróbuj online!
Wyjaśnienie
Wykorzystuje to pierwsze podejście opisane w wyzwaniu.
źródło
Rubin ,
34 5049 bajtówWypróbuj online!
Zwraca tablicę 3 liczb
[z,y,x]
.x
iy
są generowane przez podniesieniei
(pierwiastek kwadratowy z -1) do losowej potęgi między 0 a 4. Ta liczba zespolona musi być odpowiednio skalowana zgodnie zz
wartością zgodną z twierdzeniem Pitagorasa:(x**2 + y**2) + z**2 = 1.
z
Współrzędnych (który jest wytwarzany na początku) jest to po prostu liczba równomiernie rozłożone pomiędzy 1 i 1. Chociaż nie jest oczywiste, DA / dz na wskroś kuli jest stała (i wynosi na obwodzie okręgu o tym samym promieniu jak cała kula).Zostało to najwyraźniej odkryte przez Archimedesa, który opisał to w sposób bardzo podobny do rachunku różniczkowego i jest znany jako twierdzenie Archimedesa o Hat-Box. Zobacz https://brilliant.org/wiki/surface-area-sphere/
Kolejne odniesienie z komentarzy do odpowiedzi xnora. Zaskakująco krótki URL opisujący zaskakująco prostą formułę: http://mathworld.wolfram.com/Zone.html
źródło
[z, x+yi]
, zostawię go takim, jakim jest, chyba że powiesz, że to jest w porządku.z*z
zamiastz**2
?z*z
. Zredagowałem to teraz. Inną rzeczą, którą mogłem zrobić, to zastąpićrand*4
czymś takimz*99
lubx*9E9
(skutecznie ograniczając możliwe wartości do bardzo cienkiej spirali na kuli), ale myślę, że to obniża jakość losowości.05AB1E ,
2322 bajtówImplementuje drugi algorytm.
Wypróbuj online lub uzyskaj kilka losowych wyników .
Wyjaśnienie:
UWAGA: 05AB1E nie ma wbudowanej funkcji pobierania losowej wartości dziesiętnej z zakresu . Zamiast tego tworzę listę w przyrostach co i wybieram losowe wartości z tej listy. Ten przyrost może być zmieniony na zmieniając się w kodzie (choć byłoby stać raczej powolny ..).[0,1) 0.00001 0.000000001
5
9
źródło
TI-BASIC, 15 bajtów *
Za pomocą algorytmu „wygeneruj 3 normalnie rozłożone wartości i znormalizuj ten wektor”.
Zakończenie programu wyrażeniem automatycznie drukuje wynik na ekranie głównym po zakończeniu programu, więc wynik jest faktycznie pokazywany, a nie tylko generowany i zakłócany.
*:
randNorm(
jest tokenem dwubajtowym , pozostałe to tokeny jednobajtowe . Policzyłem początkowy (nieunikniony):
, bez tego będzie to 14 bajtów. Zapisany jako program o nazwie jednoliterowej zajmuje 24 bajty pamięci, w tym 9 bajtów narzutu na system plików.źródło
JavaScript (ES7),
77 7675 bajtówImplementuje 3 rd algorytm użyciu .sin(ϕ)=sin(cos−1(z))=1−z2−−−−−√
Wypróbuj online!
Skomentował
JavaScript (ES6), 79 bajtów
Implementuje 2 nd algorytmu.
Wypróbuj online!
Skomentował
źródło
Przetwarzanie 26 bajtów
Pełny program
To jest implementacja https://github.com/processing/processing/blob/master/core/src/processing/core/PVector.java
źródło
Python 2 , 86 bajtów
Wypróbuj online!
Implementuje pierwszy algorytm.
Python 2 ,
107103 bajtówWypróbuj online!
Implementuje drugi algorytm.
źródło
Haskell ,
125123119118 bajtówWypróbuj online!
Wykonuje losowanie trzech mundurów i próbkę odrzucenia.
źródło
JavaScript, 95 bajtów
Państwo
niepotrzebują nie do wejściaa
.źródło
Julia 1.0 , 24 bajty
Wypróbuj online!
Rysuje wektor 3 wartości, narysowany z rozkładu normalnego wokół 0 z odchyleniem standardowym 1. Następnie je normalizuje.
źródło
randn()
, z kilku szybkich testów, nie wydaje się być związany z wymaganym zakresem. Nie obejmuje to również sprawdzaniahypot()
zwrotu wartości>1
, którą należy odrzucić.randn
symuluje ze standardowego rozkładu normalnego, a nie jednolitego (0,1), więc to podejście jest identyczne z R.[-1,1)
to dzielenie się przez nich przez przeciwprostokątna, która będzie>1
, kompensuje to? To mnie zastanawia, czy trójnik w moim rozwiązaniu jest konieczny ...MathGolf ,
211918 bajtówImplementacja drugiego algorytmu.
Wypróbuj online lub zobacz kilka innych wyników jednocześnie .
Wyjaśnienie:
źródło
Java 8 ( zmodyfikowany trzeci algorytm @Arnauld ),
131126119111109 bajtówPort @Arnauld JavaScript odpowiedź „s , więc upewnij się, aby go upvote!
-2 bajty dzięki @ OlivierGrégoire .
Jest to realizowane jako:
Wypróbuj online.
Poprzednia implementacja trzeciego algorytmu (
131126119 bajtów):Wdrożony jako:
Wypróbuj online.
Wyjaśnienie:
Java 8 (drugi algorytm),
153143 bajtyWypróbuj online.
Drugi algorytm:
źródło
sqrt(1-k*k)
faktycznie oszczędza więcej bajtów w Javie niż w JS. :)M.sin
, 1xM.cos
i 1xM.acos
, twoje podejście używa 2xM.sin
i 1xM.sqrt
, stąd najczęściej pochodzą dodatkowe zapisane bajty. :)double[]
, ponieważ nie zmienia to liczby bajtów.)Japt , 20 bajtów
Implementacja drugiego algorytmu przez port Arnaulda .
Sprawdź to
źródło
Pyth , 24 bajty
Wypróbuj online!
Wykorzystuje algorytm nr 2
źródło
OCaml ,
1109995 bajtówEDYCJA: Ogoliłem niektóre bajty , wstawiając i , zastępując pierwszy przez a , i wykorzystując skojarzenie operatora, aby uniknąć niektórych parens .i j
let ... in
fun
()
Wypróbuj online
Oryginalne rozwiązanie:
Najpierw określam:
Random.float
Funkcja OCaml obejmuje granice. Następnie,Jest to bardzo podobne do trzeciej przykładowej implementacji (z i ) z tym wyjątkiem, że wybieram i w większych odstępach, aby później uniknąć pomnożenia (z 2).ϕ=p θ=t − i j
źródło
0
i1
bezpośrednio jako współrzędnych sferycznych. Jest to niepoprawne, jak pokazano w uwagach 3 i 4 wyzwania, ponieważ kończy się to tendencją do biegunów kuli. Możesz to poprawić, stosując metodę przedstawioną w uwadze 4.