デイ2のランダムゴルフ:正規分布の数値


12

シリーズについて

まず、これを他のコードゴルフチャレンジと同様に扱い、シリーズについてまったく心配することなく答えることができます。ただし、すべての課題にリーダーボードがあります。最初の投稿で、シリーズに関する詳細情報とともにリーダーボードを見つけることができます。

このシリーズにはたくさんのアイデアが並んでいますが、将来の課題はまだはっきりしていません。何か提案があれば、関連するサンドボックスの投稿でお知らせください。

穴2:正規分布の数値

これがまだ行われていないなんて信じられない!正規分布から描画して、乱数を生成します。いくつかのルール(それらの大部分はおそらくほとんどの投稿で自動的にカバーされますが、それらのいくつかは非常に異なる言語間の結果の一貫性を確保するために配置されています):

  • あなたは取るべき入力として2非負整数シード:Sと量Nのリターンに数字のを。出力はN平均が0分散が1の正規分布から描かれた浮動小数点数のリストである必要があります。提出物に同じシードが与えられるたびにS、同じ数が生成されます。特に、で1回とで1回呼び出される場合、2つの出力の最初のエントリは同一である必要があります。さらに、少なくとも2 16個の異なる値が異なるシーケンスを生成する必要があります。(S, N1)(S, N2)min(N1, N2)S

  • 文書化された任意の組み込み乱数ジェネレーターを使用して、(ほぼ)均一な分布から数値を引き出すことができます。ただしS、それに渡すことができ、少なくとも2 16の異なるシードをサポートします。もしあなたがそうするなら、、RNGリクエストした特定の番号に対して少なくとも2 20個の異なる値を返すことができるはずです。

  • 利用可能なユニフォームRNGの範囲が狭い、シードできない、またはサポートするシードが少なすぎる場合、最初に組み込みのRNGの上に十分に大きな範囲を持つユニフォームRNGを構築するか、独自のRNGを実装する必要があります を使用し適切なRNGを種。このページはそのために役立つかもしれません。
  • 正規分布を生成するための確立されたアルゴリズムを実装しない場合は、正確性の証明を含めてください。どちらの場合でも、選択するアルゴリズムは、理論的に正確な正規分布を生成する必要があります(基礎となるPRNGの制限または精度が制限されたデータ型を除く)。
  • 実装は、浮動小数点数(少なくとも32ビット幅)を使用して返す必要がありますまたは固定小数点数(少なくとも24ビット幅)を、すべての算術演算では、選択したタイプの全幅を使用する必要があります。
  • 以下のように、正規分布またはガウス積分に直接関連する組み込み関数を使用しないでください。 Error関数やその逆関数など。

完全なプログラムまたは関数を作成し、STDIN、コマンドライン引数、関数引数、またはプロンプトを介して入力を取得し、戻り値またはSTDOUT(または最も近い代替)に出力して出力を生成できます。

SそしてN、それぞれが2 20未満の非負の整数になりますます。出力は、便利で明確なリスト形式または文字列形式です。

これはコードゴルフなので、最短の提出(バイト単位)が勝ちです。そしてもちろん、ユーザーごとの最短投稿もシリーズの総合リーダーボードに入ります。

リーダーボード

シリーズの最初の投稿はリーダーボードを生成します。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、すべての回答を見出しで開始してください。

# Language Name, N bytes

N提出のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes

(言語は現在表示されていませんが、スニペットはそれを必要とし、解析します。将来、言語ごとのリーダーボードを追加する可能性があります。)


待ってください、非整数範囲のRNGの使用は許可されていますか?
mniip

PS 2の既存の回答は[0、1)浮動小数点RNGを使用しているようですが、これは許可されていますか?
mniip

@mniipはい、均一でシード可能で、必要な数の個別のフロートを返すことができる場合、浮動小数点RNGが許可されます。
マーティンエンダー

回答:


8

Dyalog APL、33バイト

{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕

ボックスミュラー

⎕         ⍝ evaluated input
⎕rl←1+⎕   ⍝ set APL's random seed to 1+⎕ (S)
          ⍝   add 1 because ⎕rl←0 has special meaning: sets the seed randomly
{ }¨⍳N    ⍝ do the thing in braces N times
?0        ⍝ random number 0≤x<1
1○○2×A    ⍝ sin(2πA)
.5*⍨¯2×⍟B ⍝ sqrt(-2lnB)

これは他のどの言語にも負けないはずです。
ゼロファイバー

2
これはこのルールを満たしていません:「特に、(S、N1)で1回、(S、N2)で1回呼び出された場合、2つの出力の最初のmin(N1、N2)エントリは同一である必要があります。」
マリヌス

@marinusありがとう、修正。私も特別な意味を持っ⎕rlているS+1ために変更されました⎕rl←0
ngn

おそらく実際にはを必要としませんが、+1少なくとも2 ^ 16個の異なる値をサポートする必要があるというだけです。そのため、[1..2 ^ 16]の範囲で正しく動作しても問題ありません。
マリヌ

S = 0は計算を繰り返し不可能にし、上記で引用したルールに違反します。
-ngn

8

R、68バイト

function(S,N){set.seed(S);sqrt(-2*log(runif(N)))*cos(2*pi*runif(N))}

これは、runif()一様分布からランダムな逸脱を生成する関数を使用します。乱数生成のシードは、を使用して指定さset.seed()れます。デフォルトでは、2 ^ 19937-1の周期でMersenne-Twisterアルゴリズムが使用されます。

結果は、計算された標準法線偏差を含む長さNのRベクトルです。

これは、Box-Mullerメソッドを使用します。2つの独立した一様ランダム変数UおよびVに対して、 enter image description here


それがRで有効な構文である場合は、除外することができますf=(名前のない関数があなたの言語のものであれば、関数に必ずしも名前を付ける必要はありません)。
マーティンエンダー

@MartinBüttner:提案に感謝しますが、私の知る限り、Rは名前のない関数をどうするかわかりません。
アレックスA.

また、エラーメッセージが常に表示されError: unexpected '}' in "f=fu...ますが、and を呼び出すと、同じ最初の番号が表示されますか?f(0,1)f(0,2)
-flawr

4

Dyalog APL、 42 34

{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}

これは、 S左引数とN右引数。

     5{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}10
3.019132549 ¯0.2903143175 ¯0.7353414637 1.421417015 2.327544764 ¯0.00005019747711 ¯0.9582127248 ¯0.2764568462
      ¯0.1602736853 ¯0.9912352616
     5{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}20
3.019132549 ¯0.2903143175 ¯0.7353414637 1.421417015 2.327544764 ¯0.00005019747711 ¯0.9582127248 ¯0.2764568462
      ¯0.1602736853 ¯0.9912352616 0.642585109 ¯0.2450019151 ¯0.415034463 0.03481768503 ¯0.4621212815 ¯0.760925979
      0.2592913013 1.884867889 ¯0.9621252731 0.3062560446

これは、Dyalog APLの組み込みランダム演算子を使用した、Box-Muller変換の実装です ?あり、デフォルトでは64ビット値を返すMersenneツイスターであり、これで十分です。

説明:

  • ⎕RL←⍺:ランダムシードを ます。
  • ?⍵2⍴0: 生む 0〜1の乱数のペアをます。
  • {...}/:各ペアに次の機能を適用します。
    • (.5*⍨¯2×⍟⍺)×1○⍵×○2Z0値を計算します(sqrt(-2 ln ⍺)×cos(2π⍵))。

1
v14.0では、0〜1 ?0の浮動小数点数を返します。
ngn

3

Perl、67

sub f{srand$_[0];map{cos(atan2(1,1)*rand 8)*sqrt-2*log rand}1..pop}

他のエントリと同様にボックスミュラー。 fパラメータを順番に受け取りますS, N

使用する:

$ perl -le 'sub f{srand$_[0];map{cos(atan2(1,1)*rand 8)*sqrt-2*log rand}1..pop}print for f(5,3)'
-1.59212831801942
0.432167710756345
-0.533673305924252

3

Java、164 161バイト

class B extends java.util.Random{B(int s,int n){super(s);for(;n-->0;System.out.println(Math.sqrt(-2*Math.log(nextDouble()))*Math.cos(2*Math.PI*nextDouble())));}}

これは、関数を介して入力を受け取り、stdoutを介して出力を受け取ります。Box-Mullerメソッドを使用します。


5
s=0;s++<n;-> ;n-->0;
ジオビット

1
@Geobitsはラムダのように見えます:D
TheNumberOne

3

Commodore 64 Basic、76 70 63バイト

1INPUTS,N:S=R/(-S):F┌I=1TON:?S●(-2*LOG(R/(1)))*S╮(2*π*R/(1)):N─

PETSCII文字セットにはUnicodeに存在しないいくつかの記号が含まれているため、置換を行いました:/= SHIFT+N= SHIFT+O= SHIFT+Q= SHIFT+I =SHIFT+E

これにより、標準のBox-Muller変換が実装され、数値が生成されます。Commodore 64 Basicには2文字のショートカットがあるため、変換のsin(x)半分を選択しましたsin()ありますが、ではないためましたcos()

マニュアルにはそうではないと記載されていますが、引数の値RND 重要です:負の数が渡されると、乱数ジェネレータは単に再シードされず、その番号で再シードされます。これにより、シードがはるかに簡単になります。POKE。5つのメモリ位置何もしないで呼び出すだけです。RND、コードが2行/ 121バイトから1行/ 76バイトに減少します。

編集:私は2つのINPUTステートメントを組み合わせることができ、その後のスペースTOはオプションである。

編集:さらに7回ゴルフ:コモドールベーシックは、実際には組み込み定数としてPiを持っています、そして、それは現代のキーボードでさえタイプ可能SHIFT+PgDnです(あなたが疑問に思っているなら)。


3

80386マシンコード、72バイト

コードのHexdump:

60 8b 7c 24 24 33 ed 8d 75 fb 8d 46 79 f7 e2 f7
f6 8b da b3 7f 0f cb d1 eb 89 1f d9 07 d9 e8 de
e9 33 ee 75 e5 d9 ed d9 c9 d9 f1 dc c0 d9 e0 d9
fa d9 c9 d9 eb de c9 dc c0 d9 ff de c9 d9 1f 83
c7 04 e2 c6 61 c2 04 00

ソースコードは次のとおりです(Visual Studioでコンパイルできます)。

__declspec(naked) void __fastcall doit(int count, unsigned seed, float* output)
{
    _asm {
                                // ecx = count
                                // edx = seed
        // save registers
        pushad;
        mov edi, [esp + 0x24];  // edi = pointer to output
        xor ebp, ebp;           // ebp = 0
        lea esi, [ebp - 5];     // esi = 4294967291 (a prime number)

    myloop:
        // Calculate the next random number
        lea eax, [esi + 121];   // eax = 116
        mul edx;
        div esi;
        mov ebx, edx;

        // Convert it to a float in the range 1...2
        mov bl, 0x7f;
        bswap ebx;
        shr ebx, 1;

        // Convert to range 0...1 and push onto the FPU stack
        mov [edi], ebx;
        fld dword ptr [edi];
        fld1;
        fsubp st(1), st;

        // Make 2 such random numbers
        xor ebp, esi;
        jnz myloop;

        // Calculate sqrt(-2*ln(x))
        fldln2;
        fxch;
        fyl2x;
        fadd st, st(0);
        fchs;
        fsqrt;

        // Calculate cos(2*pi*y)
        fxch st(1);
        fldpi;
        fmul;
        fadd st, st(0);
        fcos;

        // Calculate and write output
        fmulp st(1), st;
        fstp dword ptr [edi];
        add edi, 4;

        // Repeat
        loop myloop

        // Return
        popad;
        ret 4;
    }
}

ここでは、レーマー乱数ジェネレーターを使用します。次のアルゴリズムを使用します。

x(k+1) = 116 * x(k) mod 4294967291

ここで、4294967291は大きな(2 ^ 32-5)素数であり、116はそのプリミティブrootである小さな(128未満。以下を参照)数です。バイナリ表現(01110100)でゼロと1の多かれ少なかれランダムな分布を持つプリミティブルートを選択しました。シードがゼロでない場合、このRNGの最大可能期間は4294967290です。


ここで使用した比較的小さな数値(116および4294967291、-5としても表すことができます)により、lea命令のエンコードを利用できます。

8d 46 79     lea eax, [esi+121]

数値が1バイトに収まる場合、3バイトに組み立てられます。


乗算と除算は、作業レジスタとしてedxeaxを使用します。これがseed関数の2番目のパラメーターを作成した理由です(fastcall呼び出し規約はedx2番目のパラメーターを渡すために使用します)。さらに、最初のパラメーターはに渡されますecx。これは、カウンターを保持するのに適した場所です。ループは1つの命令で編成できます。

e2 c6        loop myloop

整数を浮動小数点数に変換するために、単精度浮動小数点数の表現を活用しました。ビットパターン001111111に上位9ビット(指数)を設定し、下位23ビットをランダムのままにすると、 1 ... 2の範囲の乱数を取得します。ここからアイデアを取りました。上位9ビットを設定するために、いくつかのビット操作を使用しましたebx

mov ebx, edx;    xxxxxxxx|yyyyyyyy|zzzzzzzz|aaaaaaaa
mov bl, 0x7f;    xxxxxxxx|yyyyyyyy|zzzzzzzz|01111111
bswap ebx;       01111111|zzzzzzzz|yyyyyyyy|xxxxxxxx
shr ebx, 1;      00111111|1zzzzzzz|zyyyyyyy|yxxxxxxx

2つの乱数を生成するために、2回の繰り返しのネストされたループを使用しました。私はそれを整理しましたxor

xor ebp, esi;    first time, the result is -5
jnz myloop;      second time, the result is 0 - exit loop

浮動小数点コードはBox-Muller変換を実装します。


2

ハスケル、118  144 

import System.Random;h z=let(u,r)=random z in(cos$2*pi*fst(random r)::Float)*sqrt(-2*log u):h r;g=(.(h.mkStdGen)).take

使用例:

*Main> g 3 0x6AE4A92CAFA8A742
[0.50378895,-0.20593005,-0.16684927]
*Main> g 6 0x6AE4A92CAFA8A742
[0.50378895,-0.20593005,-0.16684927,1.1229043,-0.10026576,0.4279402]
*Main> g 6 0xE09B1088DF461F7D
[2.5723906,-0.5177805,-1.3535261,0.7400385,3.5619608e-3,-8.246434e-2]

の戻り値の型randomはに制限されてFloatおりrandom、[0、1)で均一な浮動小数点を生成します。それ以降は、リスト生成のための無意味な魔法を備えた単純なボックスミュラー式です。


2

Golflua、63 70

Golfluaの情報と手順。

\g(n,s)`_ENV,b=M,{}rs(s)~@i=1,n b[i]=q(l(r()^-2))*c(r()*pi)$~b$

値を含むテーブルを返します。私が使用している例では~T.u( )、これはreturn table.unpack( )lua と同じです。

> ~T.u(g(3,1234567))
0.89302672974232 0.36330401643578 -0.64762161593981
> ~T.u(g(5,1234567))
0.89302672974232 0.36330401643578 -0.64762161593981 -0.70654636393063 -0.65662878785425
> ~T.u(g(5,7654321))
0.3867923683064 -0.31758512485963 -0.58059120409317 1.2079459300077 1.1500121921242

関数の環境をM(別名math)に設定することで、多くの文字が保存されました。


2

SAS、108

これより短い回答をRに既に投稿しましたが、PPCGにはSASの回答がほとんどないので、別の回答を追加してみませんか?

%macro f(s,n);data;do i=1 to &n;x=sqrt(-2*log(ranuni(&s)))*cos(8*atan2(1,1)*ranuni(&s));put x;end;run;%mend;

いくつかの空白がある場合:

%macro f(s, n);
    data;
        do i = 1 to &n;
            x = sqrt(-2 * log(ranuni(&s))) * cos(8 * atan2(1, 1) * ranuni(&s));
            put x;
        end;
    run;
%mend;

これはのように呼び出すことができるマクロを定義し%f(5, 3)ます。マクロは整数1からNをループするデータステップを実行し、各反復でBox-Mullerを使用してランダムな標準偏差を計算し、putステートメントを使用してログに出力します。

SASにはpiの組み込み機能がないため、できることはアークタンジェントで近似することです。

ranuni()関数(推奨されていませんが、必要な文字数が新しい関数よりも少ない)は、一様分布から乱数を返します。SASのドキュメントでは、期間が2 ^ 31-2である以外、RNGの実装に関する詳細はあまり説明していません。

SASマクロでは、マクロ変数は先行で参照され、&実行時にそれらの値に解決されます。

おそらく目撃されたように、SASはコンテストの実際の候補者になることはめったにありません。


2

Java、193バイト

これは現在のJavaリーダーに勝るものではありませんが、別の計算方法を示すためにとにかく投稿することにしました。OpenJDKのゴルフバージョンですnextGaussian()

class N extends java.util.Random{N(int s,int n){super(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*nextFloat()-1)*v)v=2*nextFloat()-1;}}

改行あり:

class N extends java.util.Random{
    N(int s,int n){
        super(s);
        for(float a,v;
            n-->0;
            System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))
                for(a=0;
                    a>=1|a==0;
                    a=v*v+(v=2*nextFloat()-1)*v)v=2*nextFloat()-1;
    }
}

2
マルサグリアを使用するための+1(または単純なボックスミュラーを使用しないため);)
マーティンエンダー

これはラムダにすることはできませんか?次のようなものです(s,n)->{java.util.Random r=new java.util.Random(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*r.nextFloat()-1)*v)v=2*r.nextFloat()-1;}
ジャスティン

2
@Quincunx 1バイトでした。しかし、メタに関する現在のコンセンサスがどうであれ、関数宣言を非カウントコードに隠すのは好きではありません。私にとっては1バイトの価値があります;)
Geobits

2

T-SQL、155バイト

CREATE PROC R(@S BIGINT,@N INT)AS
DECLARE @ INT=0,@K INT=8388607WHILE @<@N
BEGIN
SELECT SQRT(-2*LOG(RAND(@S*@%@K)))*COS(2*PI()*RAND(@S*9*@%@K))SET @+=1
END

SとNがそれぞれシードとNであるT-SQLにはSTD_INがないため、EXEC RS、Nで使用します。Sは、S> 2 ^ 16のときに「ランダム」(RAND(seed)は非常に悪い乱数の実装)シーケンスを生成します(おそらくそれより前ですが、保証しません)。これまでのほとんどのソリューションと同様にBox-Mullerを使用します。8388607は2 ^ 23-1であり、2 ^ 20個の異なる値を生成することが望まれます。


2

Powershell、164バイト

Param($s,$n)$q=2147483647
$a=GET-RANDOM -SETSEED $s
FOR(;$n---gt0;){$a=GET-RANDOM
$b=GET-RANDOM
[math]::SQRT(-2*[math]::LOG($a/$q))*[math]::COS(2*[math]::PI*$b/$q)}

Box-Mullerでのほとんどの回答と同じです。Powershellの使用経験はあまりないので、ゴルフのヘルプをいただければ幸いです。


2

ルビー、72バイト

->n,s{include Math;srand s;n.times{p sqrt(-2*log(rand))*sin(2*rand*PI)}}

入力(ラムダ関数として):

f.(6, 12353405)

出力:

-1.1565142460805273
0.9352802655317097
1.3566720571574993
-0.9683973210257978
0.9851210877202192
0.14709635752306677

PS:これをさらにゴルフできるかどうか知りたい。私はただの初心者です。


@MartinBüttner最近私はCを使いすぎていたと思う。全く忘れていました。
ゼロファイバー

2

Matlab、77

最初の入力はn、2番目のものでなければなりませんs

a=input('');
rand('seed',a(2));
for i=1:a;
    (-2*log(rand))^.5*cos(2*pi*rand)
end

2

オクターブ、91 96 88バイト

function r=n(s,n)rand("seed",s);x=rand(2,n);r=cos(2*pi*x(1,:)).*sqrt(-2*log(x(2,:)));end

または、空白を使用して:

function r=n(s,n)
  rand("seed",s);
  x=rand(2,n);
  r=cos(2*pi*x(1,:)).*sqrt(-2*log(x(2,:)));
end

シードを前もって設定し、Box-Muellerメソッドを使用します。

NB:Octaveは乱数の配列の生成を許可し、これらの配列に対して標準操作を使用して配列出力を生成できます。.*オペレータが結果を生成するために2つの配列の要素ごとの乗算です。


これは条件を満たしていないと思います。もしあなたが電話n(0,1)をしn(0,2)て最初の番号が変わったら、あなたはそうしますか?
-flawr

がらくた、あなたは正しいです。修正しましたが、5バイトかかりました
...-dcsohl

2

Pyth、32バイト

Pythの新しい機能により、スーパークォートでPythonが使用されなくなりました。さらに別のボックスミューラー。

 .xvzVQ*@_y.lOZ2.71 2.ty*3.14OZ1

最初のスペースは重要です。

.xvz             Seed RNG with evaluated input
VQ               For N in second input
*                Multiplication
 @       2       Square root
   _y            Times negative 2
    .l )         Natural log
     OZ          Of random float (RNG with zero give [0, 1) float)
 .t       1      Cosine from list of trig functions
  y              Double
   *             Multiplication
    .nZ          Pi from constants list
    OZ           Random Float

シーディングはオンラインインタープリターでは機能しないようですが、ローカルバージョンでは正常に機能します。オンライン通訳は修正されているようですので、ここにパーマリンクがあります:permalink


1
これは.nZ、質問されたときに実装されなかったPyth()の機能を使用します。(実際に今日実装されました。)したがって、この回答は競合の一部であってはなりません(meta.codegolf.stackexchange.com/questions/4867/…)。
ジャクベ

K、32文字の解決策に
戻る-Maltysen

ええ、それは良いでしょう。回答の別のセクションで、新しいソリューションを披露することができます。ただし、競合するコードは、古いPythで動作するものでなければなりません。
ジャクベ

1
ところで、私は32のソリューションも有効であるとは思わない。初期化されたランダムシードを使用するため、約5日前に追加されました。
ジャクベ

1

STATA、85バイト

di _r(s)_r(n)
set se $s
set ob $n
g a=sqrt(-2*ln(runiform()))*cos(2*runiform()*_pi)
l

標準入力(最初の数字はS、次にN)を介して入力を受け取ります。シードをSに設定します。観測の数をNに設定します。変数を作成し、その値をBox Muller変換値に設定します(表示については@Alexに感謝します)。次に、テーブルのすべての観測値を列ヘッダーaと観測値の横に一覧表示します。これらが大丈夫でない場合はお知らせください。ヘッダーや観測番号を削除できます。


1

R、89バイト

私はRが以前に行われたことを知っていますが、他の誰もが使用したBox-Mullerとは異なるアプローチを示したかったのです。私のソリューションは、中央極限定理を使用しています。

f=function(S,N){set.seed(S);a=1000;for(i in(1:N)){print(sqrt(12/a)*(sum(runif(a))-a/2))}}

1
中心極限定理は「選択するアルゴリズムは理論的に正確な正規分布を生成する必要がある」という条件を満たしていません。合計する変数の数に関係なく、合計が有限である限り、正規分布は常に近似値になります。(中央極限定理は良いアイデアですaが、結果が「公平」になるようにコードでどの値を使用すべきかが明確でないため、正確に除外する必要がありました。)
Martin Ender 2015

1
それは一撃の価値があった;)
ミハル

1

TI-Basic、74バイト

Prompt S,N:S→rand:For(X,1,N:0→A:0→V:0→W:While A≥1 or A=0:2rand-1→V:2rand-1→W:V²+W²→A:End:Disp VW√(Aֿ¹-2log(A:End

1      1111111   11   1111111111111111111     1111   111111   1111111   11111111111111  11    111111111   111

¹実際には逆演算子です。


1

Perl, 150 108 107 bytes

This uses the Marsaglia Polar Method. Called with f(S, N).

Moved the assignment of $a into the calculation of $c.

107:

sub f{srand$_[0];map{do{$c=($a=-1+2*rand)**2+(-1+2*rand)**2}until$c<1;print$a*sqrt(-2*log($c)/$c)}1..$_[1]}

Removed spare number storage and the definition of $b.

108:

sub f{srand$_[0];map{do{$a=-1+2*rand,$c=$a**2+(-1+2*rand)**2}until$c<1;print$a*sqrt(-2*log($c)/$c)}1..$_[1]}

150:

sub f{srand$_[0];map{$h?$h=!print$s:do{do{$a=-1+2*rand,$b=-1+2*rand,$c=$a*$a+$b*$b}until$c<1;$d=sqrt(-2*log($c)/$c);$s=$b*$d;$h=print$a*$d;}}1..$_[1]}

1

Swift, 144 142

Nothing clever, just seeing how Swift works.

import Foundation;func r(s:UInt32,n:Int){srand(s);for i in 0..<n{println(sqrt(-2*log(Double(rand())/0xffffffff))*sin(2*Double(rand())*M_PI))}}

I was hoping I could use (0...n).map{} but it the compiler doesn't seem to recognise map{} unless you use a parameter.


of course...? it's forEach if you don't want a return value, and I'm pretty sure the _ in is compulsory
ASCII-only

what's the /0xffffffff for btw
ASCII-only

1

Haskell, 97 bytes

import System.Random
h(a:b:c)=sqrt(-2*log a::Float)*cos(2*pi*b):h c
f a=take a.h.randoms.mkStdGen

Try it online!

Just your basic Box-Muller transformation, on an infinite list of random numbers.



0

SmileBASIC, 81 bytes

Well, now that I've answered the first question, I have to do all the rest...

Generating random numbers is cheap, but seeding the RNG uses the longest builtin function in the language, RANDOMIZE.

DEF N S,N
RANDOMIZE.,S
FOR I=1TO N?SQR(-2*LOG(RNDF()))*COS(PI()*2*RNDF())NEXT
END

Maybe there's some way to optimize the formula. I don't see how it's required to use two RNG calls.


It is required to have two independent samples for the Box-Muller transformation
ASCII-only
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.