球上のランダムポイント


31

チャレンジ

入力を受け取らず、理論的に均一なランダム方向に長さ1ベクトルを出力するプログラムまたは関数を作成します。

これは、x 2 + y 2 + z 2 = 1で記述される球上のランダムポイントに相当します。

x2+y2+z2=1

そのような分布をもたらします

半径1の球上の点のランダム分布。

出力

方程式x2+y2+z2=1が精度の限界に当てはまる理論的に均一なランダム分布からの3つのフロート。

チャレンジ発言

  • ランダム分布は理論的に均一である必要があります。つまり、擬似乱数ジェネレーターを実数からの真のRNGに置き換えると、球体上の点のランダムな分布が均一になります。
  • 一様分布から3つの乱数を生成し、それらを正規化することは無効です。3次元空間の隅に向かって偏りがあります。
  • 同様に、一様分布から2つの乱数を生成し、それらを球座標として使用することは無効です。球の極に向かってバイアスがかかります。
  • 適切な均一性は、以下を含むがこれらに限定されないアルゴリズムによって達成できます。
    • 0付近の正規(ガウス)分布から3つの乱数xyzを生成し、それらを正規化します。 0
    • 3つの乱数発生するxy及びzから均一な範囲の分布(1,1)。ベクトルの長さをl = で計算しますl=x2+y2+z2。次に、l>1場合、ベクトルを拒否し、新しい数値セットを生成します。場合他、l1、ベクトルを正規化し、結果を返します。
    • 2つの乱数発生i及びjより均一な範囲の分布(0,1)などのような球座標に変換:
      θ=2×π×iϕ=cos1(2×j1)
      ので、xyz 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]

総論


[-1、1]で3つの実数を均一に選択し、それらの平方の合計が1でない場合、それらを拒否(および繰り返し)してもかまいませんか?
13:06のGrimmy

6
@Grimy私はその抜け穴が好きです。いいえ、許可されていません。出力の理論的にゼロチャンスがあるためです。
Jitse

@Grimyの提案は、あなたが言及した2番目の実装例に似ていませんか?このソリューションは、理論的には、出力を生成する可能性がまったくありません
Saswat Padhi

2
@SaswatPadhiいいえ、それはpi/6 ≈ 0.5236出力を生成する可能性があります。これは、単位面積の立方体に内接する球の面積だ
ルイス・Mendo

1
@LuisMendoそうですね。あなたが言及したように、その場合の確率は〜0.5です。Grimyの提案では、〜0です。
Saswat Padhi

回答:



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=(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  

変更された2番目のアルゴリズムを使用します。のベクトルを[x, y, z, 0]xmm0で返します。

説明:

push 4Fh
push 3f800000h

1と2 ^ 31の値をfloatとしてスタックにプッシュします。符号拡張によりデータが重複し、数バイト節約されます。

vbroadcastss xmm1,dword ptr [rsp+5] 2 ^ 31の値をxmm1の4つの位置にロードします。

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で2乗した長さを比較し、1に等しくない場合は値を拒否します。2乗した長さが1である場合、長さも1です。つまり、ベクトルはすでに正規化されており、平方根と除算を保存します。

pop         rax  
pop         rax 

スタックを復元します。

ret xmm0で値を返します

オンラインでお試しください


7
+1 aesenc128個の「ランダムな」ビットを生成するために使用するのは美しいです。
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

オンラインでお試しください!

-1から1までのz座標を均一に生成します。次に、半径の円でx座標とy座標が均一にサンプリングされ(1-z*z)**.5ます。

球体の分布がz座標(およびすべての座標)で因子均一であることは明らかではないかもしれません。これは、次元3にとって特別なものです。球の水平スライスの表面積がその高さに比例するというこの証明を参照してください。赤道近くのスライスの半径は大きくなりますが、極近くのスライスのタイトルはより内側になり、これら2つの効果は完全に相殺されます。

この円にランダムな角度を生成するには、虚数単位1jを0から4の間の一様にランダムな累乗に上げます。これにより、インポートが必要なトリガー関数piまたはeが不要になります。次に、実数の虚数部を抽出します。2つの座標の複素数を出力できる場合、最後の行はになります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

オンラインでお試しください!

3つの法線を生成し、結果をスケーリングします。


numpyを使用したPython 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)ます。Python 3では、これa@aはnew演算子の使用に短縮できます@


1
私はあなたの最初のアプローチが好きです。z均一な分布から修正されないままにしておくと、赤道への偏りがどのように回避されるかを理解するのに苦労しています。
Jitse

2
@Jitse球面分布は、各座標にわたって一様な因子です。これは次元3にとって特別なものです。たとえば、球のスライスの表面積がその高さに比例するというこの証明を参照してください。これは赤道に偏っているという直観に関して、赤道近くのスライスは半径が大きいのに対し、極近くのスライスはより内側にタイトルが付けられ、より多くの面積が与えられることに注意してください。
xnor

非常に素晴らしい!明確化と参照をありがとう。
Jitse

@Jitseありがとう、私はそれを体に追加しました。しかし、私はポジティブなサンプリングのみであることに気付きz、数バイトで修正しました。
xnor

1
@Jitse実際、球体の表面積は、それを囲むシリンダーの外側の表面積に等しくなります!
ニール

13

オクターブ40 33 22バイト

3D標準正規分布をサンプリングし、ベクトルを正規化します。

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

オンラインでお試しください!


オクターブの場合のみ(すなわちないMATLAB)、あなたがバイトを保存することができ、この
トム・カーペンター

1
@TomCarpenterありがとう!このケースでは、私たちも、省略することができるただ一つの式であるようdisp:)
flawrを

10

Unity C#、34バイト

f=>UnityEngine.Random.onUnitSphere

Unityには単位球のランダム値の組み込みがありますので、投稿したいと思いました。


+1に建てられ、あなたが少しだけ短くする機能を提出する可能性を十分に活用f=>Random.onUnitSphere
LiefdeWen

@LiefdeWen私はラムダについて知っていましたが、それが十分であるかどうかはわかりませんでした(コードゴルフの有効性の観点から)fのタイプを宣言していないためです; 使用varはメソッド内でのみ機能し、System.Func<Vector3>長くなりました。
Draco18s

1
codegolfでは、関数を返すことはまったく問題ありません。また、宣言をカウントする必要もありません。つまり、動的パラメーターを使用して巧妙なことを行うことができます。また、最後のセミコロンもカウントしません。ただし、追加するステートメントを使用してすべてカウントします。そのため、バイトカウントにはusingを含める必要があります。しかしf=>Random.onUnitSphere、完全に有効な提出です
LiefdeWen

@LiefdeWenええ、宣言がどのように処理されているのか確信が持てず、「メタを検索する」という気持ちになりませんでした。
Draco18s

f=>UnityEngine.Random.onUnitSphereあなたは節約using
ORACE


6

ルビー34 50 49バイト

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

オンラインでお試しください!

3つの数値の配列を返します[z,y,x]

xそして、(-1の平方根)を0から4の間のランダムなべき乗yすることによって生成されiます。この複素数はz、ピタゴラスの定理に従って、値に従って適切にスケーリングする必要があります。(x**2 + y**2) + z**2 = 1.

z(最初に生成される)座標球を介してスライスのDA / DZは定数(及び同じ半径の円の周囲長と等しい、単に間の-1と1けれども直ちに明らかではない一様に分布数であります球全体。)。

これは明らかにアルキメデスによって発見されたが、アルキメデスはそれを非常に非計算的な方法で記述し、アルキメデスのハットボックス定理として知られています。https://brilliant.org/wiki/surface-area-sphere/ご覧ください

xnorの回答に関するコメントからの別の参照。驚くほど単純な式を記述する驚くほど短いURL:http : //mathworld.wolfram.com/Zone.html


@Jitse zの高い値でxとyを縮小するのを忘れていました。事実上、ポイントは円柱を定義しました。現在は修正されていますが、多くのバイトがかかります!出力が複素数で表現できる場合は、数を節約できます[z, x+yi]。それでよければ、そのままにしておきます。
レベルリバーセント

いいね!私はこのアプローチが本当に好きです。一貫性を保つために、必要な出力は3つのフロートであるため、このままにしておくことをお勧めします。
10:09のJitse

z*z代わりに使用しないのはなぜz**2ですか?
バリューインク

@ValueInkええ、ありがとうございz*zます。今編集しました。私ができる他のことは、または(球上の非常に細かい螺旋に可能な値を効果的に制限する)のrand*4ようなものに置き換えることですが、それはランダムの品質を低下させると思います。z*99x*9E9
レベルリバーセント

4

05AB1E23 22 バイト

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

2番目のアルゴリズムを実装します。

オンラインで試す、さらにランダムな出力を入手してください

説明:

[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<1l1lx0<x1l<0.51

@Jitse Ok、私のJavaと05AB1Eの両方の回答に正規化を実装しました。私は今、すべてが正しいことを願っています。
ケビンクルーッセン

v1v==1v<10<x1l1

4

TI-BASIC、15バイト*

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

アルゴリズムを使用して、「3つの正規分布値を生成し、そのベクトルを正規化します」。

式を使用してプログラムを終了すると、プログラムの終了後に結果がホームスクリーンに自動的に出力されるため、結果が生成されてブラックホール化されるだけでなく、実際に表示されます。

*:randNorm( 2バイトのトークンで、残りは1バイトのトークンです。最初の(避けられない)を数えましたが:、それなしでは14バイトになります。1文字の名前でプログラムとして保存すると、24バイトのメモリが必要になります。これには9バイトのファイルシステムオーバーヘッドが含まれます。


3

JavaScript(ES7)、 77 76  75バイト

を使用して、3 番目のアルゴリズムを実装します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
実装がバイトカウントの一部ではないことを明確にすることができます。私は最初の読書でそれを逃し、それからダブルテイクをしました。
レベルリバーセント

Iしかし、実装は私と本質的に同じアプローチを使用することのような
レベル川セント

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

オンラインでお試しください!

最初のアルゴリズムを実装します。


パイソン2107の 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番目のアルゴリズムを実装します。


2
@RobinRyderこの実装は、チャレンジで指定されている有効な初期長が1より大きいベクトルを拒否します。
Jitse

@Jitseそう、ごめんなさい。コードを読み間違えました。
ロビンライダー

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]

オンラインでお試しください!

3つのユニフォームランダムと拒否サンプリングを行います。


ランダムは(-1,1)ではなく分布(0,1)からのものであるように見えるため、球の1/8のみがカバーされます。
Jitse

@Jitse gotcha、気づいてくれてありがとう。
Angs

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

オンラインでお試しください!

標準偏差1で0付近の正規分布から描画された3つの値のベクトルを描画します。次に、それらを正規化します。


randn()、いくつかの簡単なテストから、必要な範囲に縛られていないようです。また、これには、拒否されるhypot()値を返すためのチェックが含まれていません>1
シャギー

3
@Shaggy randnは、均一(0,1)分布ではなく標準正規分布からシミュレートするように見えるため、このアプローチはRのものと同一です。
ジュゼッペ

@ジュゼッペはい、まさに!
user3263164

@ジュゼッペ、私はこの挑戦の背後にある数学を適切に把握していないかもしれないと思いますが、あなたが正しく理解しているなら、フロートのいずれかが境界[-1,1)によって分割されている場合斜辺は、どちらになるでしょう、それを>1相殺しますか?それは私のソリューションの三元が必要かどうか疑問に思います...
シャギー

いいえ@Shaggy、正常/ガウス分布は、参照、均一ていないことがいくつかの特性(具体的には、回転不変性)を有し、このコメントは、例えば、
ジュゼッペ

2

MathGolf21 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(@Arnauldの変更された3番目のアルゴリズム)、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;}

Port of @ArnauldのJavaScriptの回答なので、必ず彼に賛成してください!@OlivierGrégoireの
おかげで-2バイト。

これは次のように実装されます。

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(1)== 1なのでsqrtは不要です。だから私はゴルフの提案に賛成です。
オリビエグレゴワール

1
109バイトdouble[]バイトカウントを変更しない代わりに、文字列出力を使用できます。)
OlivierGrégoire

1

ジャプト、20バイト

アルノーの実装第二アルゴリズム。

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

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

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

OCamlのRandom.float関数には境界が含まれます。その後、

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

ϕ=pθ=tij


1
私はこの言語にはあまり馴染みがありませんが、球座標の間01直接にランダムな浮動小数点を使用しているようです。チャレンジの注釈3および4に示されているように、これは正しくありません。なぜなら、球体の極に偏ってしまうからです。あなたは発言4に示した方法を適用することによって、これを修正することができます
Jitse

ありがとうございました!完全にそれを見逃した。バグを修正し、答えを更新しました
Saswat Padhi

1
いいね!とてもいい最初の答え!
Jitse

ありがとう:)私はそれを100バイト未満に減らすことができました!
Saswat Padhi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.