एक गोले पर यादृच्छिक बिंदु


31

चुनौती

एक प्रोग्राम या फ़ंक्शन लिखें जो कोई इनपुट नहीं लेता है और सैद्धांतिक रूप से समान यादृच्छिक दिशा में लंबाई वेक्टर को आउटपुट करता है ।1

यह द्वारा वर्णित क्षेत्र पर एक यादृच्छिक बिंदु के बराबर है

एक्स2+y2+z2=1

इस तरह एक वितरण में जिसके परिणामस्वरूप

त्रिज्या 1 के साथ एक क्षेत्र पर अंकों का यादृच्छिक वितरण।

उत्पादन

तीन एक सैद्धांतिक रूप से समान यादृच्छिक वितरण से तैरते हैं जिसके लिए समीकरण सटीक सीमा तक सही है।एक्स2+y2+z2=1

चुनौती की टिप्पणी

  • यादृच्छिक वितरण को सैद्धांतिक रूप से समान होना चाहिए । यही है, अगर छद्म यादृच्छिक संख्या जनरेटर को वास्तविक संख्याओं से एक सच्चे RNG के साथ प्रतिस्थापित किया जाना था, तो इसका परिणाम क्षेत्र पर समान रूप से यादृच्छिक वितरण होगा।
  • एक समान वितरण से तीन यादृच्छिक संख्या उत्पन्न करना और उन्हें सामान्य करना अमान्य है: तीन आयामी स्थान के कोनों की ओर एक पूर्वाग्रह होगा।
  • इसी तरह, एक समान वितरण से दो यादृच्छिक संख्याओं को उत्पन्न करना और गोलाकार निर्देशांक के रूप में उनका उपयोग करना अमान्य है: क्षेत्र के ध्रुवों के प्रति पूर्वाग्रह होगा।
  • एल्गोरिदम द्वारा उचित एकरूपता प्राप्त की जा सकती है, लेकिन इसके लिए सीमित नहीं है:
    • सामान्य (गाऊसी) वितरण से तीन यादृच्छिक संख्याओं , और को आसपास उत्पन्न करें और उन्हें सामान्य करें। एक्सyz0
    • रेंज में एक समान वितरण से तीन यादृच्छिक संख्या एक्स , y और z उत्पन्न करें ( - 1 , 1 ) । द्वारा वेक्टर की लंबाई की गणना एल = (-1,1)l=x2+y2+z2 । फिर, यदिl>1, वेक्टर को अस्वीकार कर देता है और संख्याओं का एक नया समूह उत्पन्न करता है। वरना, अगरl1, वेक्टर सामान्य और परिणाम लौटने।
    • रेंज ( 0 , 1 ) में एक समान वितरण से दो यादृच्छिक संख्या i और j उत्पन्न करें और उन्हें गोलाकार निर्देशांक में बदलें जैसे: i(0,1)
      θ=2×π×iϕ=cos1(2×j1)
      ताकिx,yऔरzगणना x द्वारा की जा सके
      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 नहीं है, तो उन्हें (और दोहराएं) अस्वीकार करें?
ग्रिमी

6
@ जिस्म मुझे वो खामोशी पसंद है। नहीं, इसकी अनुमति नहीं है, क्योंकि किसी भी आउटपुट का सैद्धांतिक रूप से शून्य मौका है।
जितसेप

क्या आपके द्वारा उल्लिखित दूसरे उदाहरण कार्यान्वयन के समान @ ग्रिम का सुझाव नहीं है? उस समाधान में किसी भी उत्पादन के सैद्धांतिक रूप से शून्य मौका है
सस्वत पाधी

2
@SaswatPadhi नहीं, कि pi/6 ≈ 0.5236एक उत्पादन का एक मौका है। वह क्षेत्र-क्षेत्र घन में खुदा हुआ क्षेत्र है
लुइस मेंडू

1
@LuisMendo मैं देख रहा हूँ, ठीक है। संभावना उस स्थिति में ~ 0.5 है, जैसा आपने उल्लेख किया है। ग्रिम के प्रस्ताव के लिए, यह ~ 0 है।
सास्वत पाढ़ी

जवाबों:



24

आर , 23 बाइट्स

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

इसे ऑनलाइन आज़माएं!

N(0,1) वितरण के 3 अहसास उत्पन्न करता है और परिणामी वेक्टर को सामान्य करता है।

1000 अहसासों का प्लॉट:

यहाँ छवि विवरण दर्ज करें


2
क्या आप सामान्य रूप से वितरित 3 अक्ष को गोलाकार पर समान रूप से वितरित कर सकते हैं? (मैं इसे नहीं देखता हूं)
जेफरी

4
@ जेफ़्री यह संभावना / आँकड़ों में बहुत अच्छी तरह से जाना जाता है; लेकिन 2D के लिए प्रमाण (जो बड़े पैमाने पर 3 आयामों तक फैला हुआ है) लगभग है: और स्वतंत्र। फिर एफ एक्स ( एक्स ) = के - 1एक्स,Y~एन(0,1)औरएफवाई(वाई)=के-1एक्स(एक्स)=कश्मीर-12एक्स2, इसलिए आजादी सेएक्सवाई(एक्स,वाई)=कश्मीर2-1Y(y)=कश्मीर-12y2जहांजेड=(एक्स,वाई), तो यह स्पष्ट है कि के वितरणजेडकी भयावहता पर निर्भर करता हैजेड, और इस प्रकार दिशा समान रूप से वितरित किया जाता है। एक्सY(एक्स,y)=कश्मीर2-12(एक्स2+y2)=जेड(z)=कश्मीर2-12z2z=(एक्स,y)zz
ग्यूसेप

1
इसलिए, सामान्य वितरण हमें सर्कल के चारों ओर समान रूप से वितरित अंक प्रदान करता है, और परिमाण द्वारा विभाजित करने से अंक चक्र पर झूठ सुनिश्चित होते हैं
Giuseppe

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] Xmm1 के 4 पदों में 2 ^ 31 के मान को लोड करता है।

rdrand      eax  
jnc         rand  
movd        xmm0,eax

यादृच्छिक 32-बिट पूर्णांक बनाता है और इसे xmm0 के नीचे लोड करता है।

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

एक यादृच्छिक 32 बिट पूर्णांक बनाता है, इसे फ्लोट (हस्ताक्षरित) में परिवर्तित करें और -1 और 1 के बीच संख्या प्राप्त करने के लिए 2 ^ 31 से विभाजित करें।

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 aesenc128 "यादृच्छिक" बिट्स का उत्पादन करने के लिए उपयोग करना सिर्फ सुंदर है।
डॉकमैक्स

13

पायथन 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 समन्वय पर कारक वर्दी में है (और इसलिए प्रत्येक समन्वय पर)। यह आयाम के लिए कुछ विशेष है। इस प्रमाण को देखें कि एक गोले के क्षैतिज स्लाइस का सतह क्षेत्र इसकी ऊंचाई के लिए आनुपातिक है। हालांकि भूमध्य रेखा के पास के स्लाइस में एक बड़ा त्रिज्या होता है, ध्रुव के पास स्लाइस का शीर्षक अधिक आवक होता है, और यह इन दो प्रभावों को बिल्कुल रद्द कर देता है।

इस सर्कल पर एक यादृच्छिक कोण उत्पन्न करने के लिए, हम काल्पनिक इकाई 1jको 0 और 4 के बीच समान रूप से यादृच्छिक शक्ति में बढ़ाते हैं , जो हमें ट्रिगर फ़ंक्शन, पाई या ई की आवश्यकता से बचाता है, जिनमें से किसी को आयात की आवश्यकता होगी। फिर हम वास्तविक काल्पनिक भाग को निकालते हैं। यदि हम निर्देशांक के दो के लिए एक जटिल संख्या को आउटपुट कर सकते हैं, तो अंतिम पंक्ति बस हो सकती है 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

इसे ऑनलाइन आज़माएं!

तीन मानदंड बनाता है और परिणाम को मापता है।


पायथन 2 के साथ सुन्न, 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)। पायथन 3 में, a@aनए ऑपरेटर का उपयोग करने के लिए इसे छोटा किया जा सकता है @


1
मुझे आपका पहला तरीका पसंद है। मुझे यह समझने में परेशानी हो रही है कि zएक समान वितरण से, भूमध्य रेखा के प्रति पूर्वाग्रह से कैसे बचा जा सकता है।
जित्स

2
@Jitse गोलाकार वितरण प्रत्येक समन्वय पर कारक वर्दी में है। यह आयाम के लिए कुछ विशेष है। उदाहरण के लिए इस प्रमाण को देखें कि एक गोले के टुकड़े का सतह क्षेत्र इसकी ऊंचाई के लिए आनुपातिक है। अंतर्ज्ञान के बारे में कि यह भूमध्य रेखा के पक्षपाती है, ध्यान दें कि जबकि भूमध्य रेखा के पास स्लाइस का एक बड़ा त्रिज्या है, ध्रुव के पास वाले लोगों को अंदर की ओर शीर्षक दिया जाता है जो अधिक क्षेत्र देता है, और यह इन दो प्रभावों को बिल्कुल रद्द कर देता है।
xnor

बहुत अच्छा! स्पष्टीकरण और संदर्भ के लिए धन्यवाद।
जित्स

@ जीत धन्यवाद, मैंने इसे शरीर से जोड़ा। मुझे एहसास हुआ कि मैं केवल zहालांकि सकारात्मक नमूना था , और कुछ बाइट्स के लिए तय है।
xnor

1
@ जेट्स दरअसल, एक गोले का सतह क्षेत्र, एन्क्लोजिंग सिलेंडर के पार्श्व सतह क्षेत्र के बराबर होता है!
नील

13

ऑक्टेव , 40 33 22 बाइट्स

हम एक सामान्य मानक वितरण का नमूना बनाते हैं और वेक्टर को सामान्य करते हैं:

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

इसे ऑनलाइन आज़माएं!


सप्टक केवल (यानी नहीं MATLAB) के लिए, आप के साथ एक बाइट बचा सकता है इस
टॉम बढ़ई

1
@TomCarpenter धन्यवाद! इस मामले में चूंकि यह सिर्फ एक अभिव्यक्ति है, हम भी disp:)
दोष

10

एकता सी # , 34 बाइट्स

f=>UnityEngine.Random.onUnitSphere

एकता में एक इकाई है जिसमें यादृच्छिक मान हैं, इसलिए मैंने सोचा कि मैं इसे पोस्ट करूंगा।


एक निर्मित +1 का अच्छा उपयोग, आप बस थोड़ा छोटा होने के लिए एक फ़ंक्शन सबमिट कर सकते हैंf=>Random.onUnitSphere
LiefdeWen

@ लाइपडेन जब मैं लंबोदर के बारे में जानता था, तो मुझे यकीन नहीं था कि यह पर्याप्त था (कोड गोल्फ पर वैधता के संदर्भ में) क्योंकि यह घोषित नहीं कर रहा है f; का उपयोग करते हुए varकेवल एक विधि के अंदर काम करता है और System.Func<Vector3>लंबे समय तक किया गया था।
ड्रेको 18 एस

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और 0 और 4 के बीच एक यादृच्छिक शक्ति के लिए (-1 के वर्गमूल) को yबढ़ाकर उत्पन्न किया जाता है i। इस जटिल संख्या को इसके अनुसार उचित रूप से बढ़ाया जाना चाहिएz को पाइथागोरस प्रमेय के अनुसार मूल्य के अनुसार :(x**2 + y**2) + z**2 = 1.

zसमन्वय (जो पहले उत्पन्न होता है) बस के बीच -1 और 1. हालांकि तुरंत नहीं स्पष्ट है, दा / एक क्षेत्र के माध्यम से एक टुकड़ा के लिए dz स्थिर है एक समान रूप से वितरित संख्या है (और के रूप में ही त्रिज्या का एक चक्र की परिधि के बराबर पूरा क्षेत्र।)।

यह स्पष्ट रूप से आर्किमिडीज़ द्वारा खोजा गया था, जिन्होंने इसे बहुत ही गैर-परिकलन-जैसे तरीके से वर्णित किया था, और इसे आर्किमिडीज़ हैट-बॉक्स प्रमेय के रूप में जाना जाता है। देखHttps://brilliant.org/wiki/surface-area-sphere/

Xnor के उत्तर पर टिप्पणियों से एक और संदर्भ। आश्चर्यजनक रूप से सरल सूत्र का वर्णन करते हुए आश्चर्यजनक रूप से छोटा URL: http://mathworld.wolfram.com/Zone.html


@ जीत मैं z के उच्च मूल्यों पर x और y को वापस स्केल करना भूल गया। प्रभावी ढंग से अंक एक सिलेंडर को परिभाषित करते हैं। यह अब तय हो गया है, लेकिन इसकी कीमत बहुत अधिक है! अगर उत्पादन एक जटिल संख्या के साथ व्यक्त किया जा सकता है तो मैं कुछ बचा सकता हूं [z, x+yi], जब तक आप यह नहीं कहेंगे कि मैं ठीक हूं।
लेवल रिवर सेंट

अछा लगता है! मुझे वास्तव में यह दृष्टिकोण पसंद है। स्थिरता के लिए, आवश्यक आउटपुट तीन फ्लोट है, इसलिए मैं इसे इस तरह छोड़ने का सुझाव देता हूं।
10

के z*zबजाय का उपयोग क्यों नहीं z**2?
मूल्य स्याही

@ValueInk हाँ धन्यवाद मुझे एहसास हुआ कि मुझे याद होगा z*z। मैंने इसे अभी संपादित किया है। दूसरी चीज जो मैं कर सकता था, वह है rand*4जैसे कुछ के साथ z*99या x*9E9(प्रभावी रूप से गोले पर एक बहुत बढ़िया सर्पिल के लिए संभावित मूल्यों को सीमित करना) लेकिन मुझे लगता है कि यादृच्छिक की गुणवत्ता को कम करता है।
लेवल रिवर सेंट

4

05AB1E , 23 22 बाइट्स

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

दूसरा एल्गोरिथ्म लागू करता है।

इसे ऑनलाइन आज़माएं या कुछ और यादृच्छिक आउटपुट प्राप्त करें

स्पष्टीकरण:

नोट: 05AB1E के पास रेंज में एक यादृच्छिक दशमलव मान प्राप्त करने के लिए एक बिलिन नहीं है [0,1)। इसके बजाय, मैं वेतन वृद्धि में एक सूची बनाता हूं0.00001, और उस सूची से यादृच्छिक मान चुनें। इस वेतन वृद्धि को बदला जा सकता है.००,००,००,००१बदलकर 5करने के लिए 9कोड में (हालांकि यह नहीं बल्कि धीमी गति से बन जाएगा ..)।

[            # 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
का उपयोग करते हुए एल<1 समान रूप से मान्य है एल1। के लिए एकमात्र मानदंडएलएक्स क्या वह 0<एक्स1। आप के साथ बस वैक्टर स्वीकार कर सकते हैंएल<0.5अगर यह किसी भी बाइट को बचाएगा। किसी भी मूल्य के बराबर या उससे छोटा1 पूर्वाग्रह को दूर करता है।
जितेश

@Jitse Ok ने मेरे जावा और 05AB1E दोनों उत्तरों में सामान्यीकरण लागू किया। मुझे उम्मीद है कि अब सब कुछ ठीक हो जाएगा।
केविन क्रूज़सेन

@ जीत ने वास्तव में एक बाइट को चेक करके बचाया v1 जैसा v==1, के बजाय v<1। लेकिन स्पष्टीकरण के लिए धन्यवाद कि केवल0<एक्स1 एक आवश्यकता है, और एक सख्त नहीं है आवश्यकता है एल, जब तक यह है 1
केविन क्रूज़सेन

4

TI-BASIC, 15 बाइट्स *

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

एल्गोरिथ्म का उपयोग करना "3 सामान्य रूप से वितरित मूल्यों को उत्पन्न करना और उस वेक्टर को सामान्य करना"।

किसी प्रोग्राम को किसी अभिव्यक्ति के साथ समाप्त करना प्रोग्राम समाप्त होने के बाद होमस्क्रीन पर स्वचालित रूप से परिणाम प्रिंट करता है, इसलिए परिणाम वास्तव में दिखाया गया है, न कि केवल उत्पन्न और ब्लैकहोल किया गया है।

* - randNorm(एक दो बाइट टोकन है , बाकी एक बाइट टोकन हैं । मैंने प्रारंभिक (अपरिहार्य) की गिनती की है :, इसके बिना यह 14 बाइट्स होगा। एक-अक्षर के नाम के साथ एक कार्यक्रम के रूप में सहेजा गया, यह 24 बाइट्स मेमोरी लेता है, जिसमें फ़ाइल-सिस्टम ओवरहेड के 9 बाइट्स शामिल हैं।


3

जावास्क्रिप्ट (ईएस 7),  77 76  75 बाइट्स

3 आरडी एल्गोरिथ्म का उपयोग करते हुए, लागू करता हैपाप(φ)=पाप(क्योंकि-1(z))=1-z2

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(ɸ)
  ]                              //

जावास्क्रिप्ट (ईएस 6), 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
आप यह स्पष्ट करना चाहते हैं कि कार्यान्वयन आपके बाइट की गिनती का हिस्सा नहीं है। मैंने इसे पहले पढ़ने में याद किया, फिर डबल-टेक किया।
लेवल रिवर सेंट

मुझे यह पसंद है कि कार्यान्वयन अनिवार्य रूप से मेरे जैसे ही दृष्टिकोण का उपयोग करता है
लेवल रिवर सेंट

2

पायथन 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

इसे ऑनलाइन आज़माएं!

पहला एल्गोरिथ्म लागू करता है।


पायथन 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 के साथ अस्वीकार करता है, जो चुनौती में निर्दिष्ट अनुसार मान्य है।
जित्स

@ जीत सही, क्षमा करें। मैंने कोड को गलत बताया।
रॉबिन राइडर

2

हास्केल , 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 कवर हो।
जित्स

@ जितेश गोचा, ध्यान देने के लिए धन्यवाद।
आंग्स

2

जावास्क्रिप्ट, 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...)

इसे ऑनलाइन आज़माएं!

मानक विचलन के साथ 0 के आसपास एक सामान्य वितरण से खींची गई 3 मानों का एक सदिश ड्रा करता है। फिर बस उन्हें सामान्य करता है।


randn()त्वरित परीक्षणों के एक जोड़े से, आवश्यक सीमा के लिए बाध्य नहीं लगता है। इसके अलावा, इसमें hypot()एक मान लौटाने के लिए एक चेक शामिल नहीं है >1, जिसे अस्वीकार कर दिया जाना चाहिए।
झबरा

3
@ शैग्गी यह randnएक समान (0,1) एक के बजाय एक मानक सामान्य वितरण से अनुकरण प्रतीत होता है , इसलिए यह दृष्टिकोण आर वन के समान है।
ग्यूसेप

@Giuseppe हाँ, बिल्कुल!
user3263164 21

@Giuseppe, मुझे लगता है कि हो सकता है कि इस चुनौती के पीछे मैथ्स पर मेरा उचित पकड़ न हो, लेकिन, अगर मैं आपको सही तरीके से समझ रहा हूं, तो आप कह रहे हैं कि यदि कोई भी फ्लोट्स बाहर हैं, [-1,1)तो उनके द्वारा विभाजित करना कर्ण, जो होगा >1, offsets कि? कि मुझे आश्चर्य होता है कि क्या मेरे समाधान में त्रिगुट आवश्यक है ...
झबरा

@ सामान्य नहीं, सामान्य / गौसियन वितरण में कुछ गुण होते हैं (विशेष रूप से, घूर्णी चालन) जो वर्दी में होता है, देखें उदाहरण के लिए इस टिप्पणी को
ग्यूसेप

2

मठगोल्फ , 21 19 18 बाइट्स

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

दूसरा एल्गोरिथ्म का कार्यान्वयन।

इसे ऑनलाइन आज़माएं या एक ही समय में कुछ और आउटपुट देखें

स्पष्टीकरण:

{              }▲   # 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

जावा 8 ( @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 का जावास्क्रिप्ट उत्तर है , इसलिए उसे सुनिश्चित करना सुनिश्चित करें!
-2 बाइट्स @ ओलिवियरग्रेगायर के लिए धन्यवाद ।

इसे इस प्रकार लागू किया गया है:

कश्मीर=एन[-1,1)
टी=1-कश्मीर2
यू=2π×(एन[0,1))
एक्स,y,z={कश्मीर,क्योंकि(यू)×टी,पाप(यू)×टी}

इसे ऑनलाइन आज़माएं।

पिछला तीसरा एल्गोरिथ्म कार्यान्वयन ( 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);}

इस रूप में लागू किया गया:

कश्मीर=एन[-1,1)
टी=2π×(एन[0,1))
एक्स,y,z={कश्मीर,क्योंकि(टी)×पाप(ARccOS(कश्मीर)),पाप(टी)×पाप(ARccOS(कश्मीर))}

इसे ऑनलाइन आज़माएं।

स्पष्टीकरण:

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

जावा 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;}

इसे ऑनलाइन आज़माएं।

दूसरा एल्गोरिथ्म:

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)वास्तव में जावा में अधिक बाइट्स का उपयोग करने से यह जेएस में करता है। :)
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

जाप , 20 बाइट्स

2 एल्गोरिथ्म के अर्नाल्द के कार्यान्वयन का पोर्ट ।

MhV=3ÆMrJ1
>1?ß:V®/U

झसे आज़माओ

MhV=3ÆMrJ1
Mh             :Get the hypotenuse of
  V=           :  Assign to V
    3Æ         :  Map the range [0,3)
      Mr       :    Random float
        J1     :    In range [-1,1)
>1?ß:V®/U      :Assign result to U
>1?            :If U is greater than 1
   ß           :  Run the programme again
    :V®/U      :Else map V, dividing all elements by U


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

संपादित करें: कुछ बाइट्स को शालीनता से काट दिया मैं तथा j, के let ... inसाथ पहले की जगहfun , और कुछ समानता से बचने के लिए ऑपरेटर की सहानुभूति का लाभ उठाते हुए ()

इसे ऑनलाइन आज़माएं


मूल समाधान:

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])

पहले मैं परिभाषित करता हूं:

=ARccOS,  सी=क्योंकि,  रों=पापमैं~unif(0,4),  j~unif(0,2)

OCaml के Random.floatफ़ंक्शन में सीमाएं शामिल हैं। फिर,

टी=मैं(0)=मैंπ2,  पी=(j-1)

यह तीसरे उदाहरण के कार्यान्वयन (के साथ) के समान है φ=पी तथा θ=टी) - सिवाय इसके कि मैं चुनता हूँ मैं तथा j बाद में गुणा (2 के साथ) से बचने के लिए बड़े अंतराल के भीतर।


1
मैं इस भाषा से बिल्कुल परिचित नहीं हूँ, लेकिन ऐसा लगता है कि आप गोलाकार निर्देशांक के बीच 0और 1सीधे यादृच्छिक फ़्लोट्स का उपयोग करते हैं । यह गलत है, जैसा कि चुनौती टिप्पणी 3 और 4 में दिखाया गया है, क्योंकि आप क्षेत्र के ध्रुवों के प्रति पूर्वाग्रह के साथ समाप्त होते हैं। आप टिप्पणी 4 में दर्शाई गई विधि को लागू करके इसे ठीक कर सकते हैं।
जितसेप

धन्यवाद! पूरी तरह से याद किया। बग को ठीक किया और मेरे जवाब को अपडेट किया
सस्वत पाधी

1
अछा लगता है! बहुत अच्छा पहला जवाब!
8

धन्यवाद :) मैं इसे अंडर -100 बाइट्स में कम करने में सक्षम था!
सास्वत पाढ़ी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.