Golf Acak Hari Ini # 2: Angka dari Distribusi Normal


12

Tentang Seri

Pertama, Anda dapat memperlakukan ini seperti tantangan golf kode lainnya, dan menjawabnya tanpa khawatir tentang seri sama sekali. Namun, ada papan peringkat di semua tantangan. Anda dapat menemukan leaderboard bersama dengan beberapa informasi lebih lanjut tentang seri di posting pertama .

Meskipun saya memiliki banyak ide untuk seri ini, tantangan di masa depan belum ditetapkan. Jika Anda memiliki saran, beri tahu saya di pos kotak pasir yang relevan .

Lubang 2: Angka dari Distribusi Normal

Saya tidak percaya ini belum dilakukan! Anda akan menghasilkan angka acak, menggambar dari distribusi normal . Beberapa aturan (mayoritas dari mereka mungkin secara otomatis tercakup oleh sebagian besar penyerahan, tetapi beberapa dari mereka ada untuk memastikan konsistensi hasil antara bahasa yang sangat berbeda):

  • Anda harus mengambil dua bilangan bulat non-negatif sebagai input : satu seed Sdan jumlah Nangka yang akan dikembalikan. Outputnya harus berupa daftar Nangka floating point, diambil dari distribusi normal dengan rata - rata 0 dan varians 1 . Setiap kali kiriman Anda diberikan benih yang sama, Sia harus menghasilkan nomor yang sama. Secara khusus, jika itu dipanggil sekali dengan dan sekali dengan , entri pertama dari dua output harus identik. Selain itu, setidaknya 2 16 nilai yang berbeda harus menghasilkan urutan yang berbeda.(S, N1)(S, N2)min(N1, N2)S

  • Anda dapat menggunakan penghasil bilangan acak bawaan apa pun yang didokumentasikan untuk menarik bilangan dari distribusi seragam (kira-kira) , asalkan Anda dapat meneruskannya Sdan mendukung setidaknya 16 16 benih yang berbeda. Jika ya, RNG harus dapat mengembalikan setidaknya 20 nilai yang berbeda untuk setiap nomor yang Anda minta darinya.

  • Jika seragam RNG Anda yang tersedia memiliki rentang yang lebih kecil, tidak dapat diunggulkan, atau mendukung terlalu sedikit benih, Anda harus terlebih dahulu membangun RNG seragam dengan rentang yang cukup besar di atas bawaan atau Anda harus menerapkan RNG Anda sendiri menggunakan biji. Halaman ini mungkin bermanfaat untuk itu.
  • Jika Anda tidak menerapkan algoritma yang ditetapkan untuk menghasilkan distribusi normal, harap sertakan bukti kebenaran. Dalam kedua kasus tersebut, algoritma yang Anda pilih harus menghasilkan distribusi normal yang tepat secara teoritis (kecuali pembatasan PRNG yang mendasari atau tipe data presisi terbatas).
  • Implementasi Anda harus menggunakan dan mengembalikan angka floating-point (lebar minimal 32 bit) atau angka fixed-point (setidaknya lebar 24 bit) dan semua operasi aritmatika harus menggunakan lebar penuh dari tipe yang dipilih.
  • Anda tidak boleh menggunakan fungsi bawaan apa pun yang terkait langsung dengan distribusi normal atau integral Gaussian, seperti fungsi Galat atau kebalikannya.

Anda dapat menulis program atau fungsi lengkap dan mengambil input melalui STDIN, argumen baris perintah, argumen fungsi atau prompt dan menghasilkan output melalui nilai balik atau dengan mencetak ke STDOUT (atau alternatif terdekat).

Sdan Nakan menjadi bilangan bulat non-negatif, masing-masing kurang dari 20 . Output mungkin dalam format string atau daftar yang mudah, tidak ambigu.

Ini adalah kode golf, jadi pengiriman terpendek (dalam byte) menang. Dan tentu saja, pengiriman terpendek per pengguna juga akan masuk ke papan peringkat keseluruhan seri.

Papan peringkat

Posting pertama dari seri menghasilkan leaderboard.

Untuk memastikan jawaban Anda muncul, mulailah setiap jawaban dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

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

(Bahasa saat ini tidak ditampilkan, tetapi cuplikan memang membutuhkan dan menguraikannya, dan saya dapat menambahkan leaderboard berdasarkan bahasa di masa mendatang.)


Tunggu, apakah kita diizinkan menggunakan RNG non-integer?
mniip

PS 2 jawaban yang ada tampaknya menggunakan [0, 1) floating point RNG, apakah ini diizinkan?
mniip

@mniip Ya, RNG titik-mengambang diizinkan, asalkan seragam, dapat ditaburkan dan dapat mengembalikan jumlah pelampung berbeda yang diperlukan.
Martin Ender

Jawaban:


8

Dyalog APL, 33 byte

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

Kotak-muller :

⎕         ⍝ 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)

Saya cukup yakin ini tidak bisa dikalahkan oleh bahasa lain.
Zero Fiber

2
Ini tidak memenuhi aturan ini: "Secara khusus, jika dipanggil satu kali dengan (S, N1) dan sekali dengan (S, N2), entri min pertama (N1, N2) dari dua output harus identik."
marinus

@marinus Terima kasih, sudah diperbaiki. Saya juga berubah ⎕rlmenjadi S+1karena ⎕rl←0memiliki makna khusus.
ngn

Anda mungkin tidak benar-benar membutuhkannya +1, semua dikatakan bahwa Anda perlu mendukung setidaknya 2 ^ 16 nilai yang berbeda. Jadi bekerja dengan benar dalam kisaran [1..2 ^ 16] harus OK.
marinus

S = 0 akan membuat perhitungan tidak dapat diulang, yang melanggar aturan yang Anda kutip di atas.
ngn

8

R, 68 byte

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

Ini menggunakan runif()fungsi, yang menghasilkan penyimpangan acak dari distribusi yang seragam. Benih untuk pembuatan angka acak ditentukan menggunakan set.seed(), yang secara default menggunakan algoritma Mersenne-Twister dengan periode 2 ^ 19937-1.

Hasilnya adalah vektor R dengan panjang N yang berisi standar penyimpangan normal yang dihitung.

Ini menggunakan metode Box-Muller: Untuk dua variabel acak seragam independen U dan V, masukkan deskripsi gambar di sini


Jika itu sintaks yang valid dalam R, Anda dapat mengabaikan f=(fungsi tidak perlu dinamai, jika fungsi yang tidak disebutkan namanya adalah sesuatu dalam bahasa Anda).
Martin Ender

@ MartinBüttner: Saya menghargai saran itu tetapi setahu saya R tidak akan tahu apa yang harus dilakukan dengan fungsi yang tidak disebutkan namanya.
Alex A.

Selain itu, saya selalu mendapatkan pesan kesalahan Error: unexpected '}' in "f=fu..., apakah Anda yakin mendapat nomor pertama yang sama jika Anda menelepon f(0,1)dan f(0,2)?
flawr

4

Dyalog APL, 42 34

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

Ini adalah fungsi yang mengambil Sargumen kiri dan Nargumen kanannya.

     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

Ini merupakan implementasi dari transformasi Box-Muller, menggunakan operator acak ?bawaan Dyalog APL , yang secara default adalah twister Mersenne yang mengembalikan nilai 64-bit, yang seharusnya cukup.

Penjelasan:

  • ⎕RL←⍺: setel benih acak ke .
  • ?⍵2⍴0: menghasilkan pasangan angka acak antara 0 dan 1.
  • {... }/: terapkan fungsi berikut untuk setiap pasangan:
    • (.5*⍨¯2×⍟⍺)×1○⍵×○2: hitung Z0nilainya ( sqrt(-2 ln ⍺)×cos(2π⍵)).

1
Dalam v14.0 ?0mengembalikan angka floating point antara 0 dan 1.
ngn

3

Perl, 67

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

Box-Muller seperti pada entri lainnya. fmengambil parameter secara berurutan S, N.

Menggunakan:

$ 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 byte

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())));}}

Ini menerima input melalui fungsi dan output melalui stdout. Ini menggunakan metode Box-Muller.


5
s=0;s++<n;-> ;n-->0;?
Geobits

1
@ Geobits Sepertinya lambda: D
TheNumberOne

3

Commodore 64 Basic, 76 70 63 byte

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

Karena rangkaian karakter PETSCII berisi beberapa simbol yang tidak ada di Unicode, saya telah membuat pergantian: /= SHIFT+N, = SHIFT+O, = SHIFT+Q, = SHIFT+I, =SHIFT+E

Ini mengimplementasikan transformasi Box-Muller standar untuk menghasilkan angka; Saya memilih dosa (x) setengah dari transformasi karena Commodore 64 Basic memiliki pintasan dua karakter untuk sin(), tetapi tidak untuk cos().

Meskipun manual menyatakan sebaliknya, nilai argumen untuk RND melakukan hal penting: jika angka negatif dilewatkan, generator nomor acak tidak hanya diunggulkan kembali, tetapi diunggulkan kembali dengan nomor itu . Ini membuat penyemaian jauh lebih sederhana: daripada perlu ke POKElima lokasi memori, saya hanya perlu membuat panggilan do-nothing RND, yang mengurangi kode dari dua baris / 121 byte menjadi 1 baris / 76 byte.

Sunting: Memotong enam byte off dengan menyadari bahwa saya dapat menggabungkan dua INPUTpernyataan, dan bahwa ruang setelahnya TOadalah opsional.

Sunting: Dipotong tujuh lagi: Commodore Basic, pada kenyataannya, memiliki Pi sebagai konstanta bawaan, dan bahkan dapat diketik pada keyboard modern ( SHIFT+PgDn, jika Anda bertanya-tanya).


3

80386 kode mesin, 72 byte

Hexdump kode:

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

Berikut adalah kode sumbernya (dapat dikompilasi oleh 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;
    }
}

Di sini saya menggunakan generator bilangan acak Lehmer . Ini menggunakan algoritma berikut:

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

Di sini 4294967291 adalah bilangan prima besar (2 ^ 32-5), dan 116 adalah bilangan kecil (kurang dari 128; lihat di bawah) yang merupakan akar primitifnya . Saya memilih akar primitif yang memiliki distribusi nol acak yang lebih atau kurang dan yang dalam representasi biner (01110100). RNG ini memiliki periode maksimum yang mungkin adalah 4294967290, jika benih bukan nol.


Angka yang relatif kecil yang saya gunakan di sini (116 dan 4294967291, yang dapat diwakili juga sebagai -5) izinkan saya mengambil keuntungan dari leapengkodean instruksi:

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

Ia dirangkai menjadi 3 byte jika angka-angka tersebut dapat masuk ke dalam 1 byte.


Perkalian dan penggunaan divisi edxdan eaxsebagai register kerja mereka, itulah sebabnya saya membuat seedparameter kedua ke fungsi ( fastcallkonvensi pemanggilan digunakan edxuntuk melewati parameter kedua). Selain itu, parameter pertama dilewatkan ecx, yang merupakan tempat yang baik untuk menyimpan penghitung: loop dapat diatur dalam 1 instruksi!

e2 c6        loop myloop

Untuk mengkonversi integer menjadi angka floating-point, saya mengeksploitasi representasi angka floating-point presisi tunggal: jika saya mengatur tinggi 9 bit (eksponen) ke pola bit 001111111, dan meninggalkan 23 bit rendah secara acak, saya akan dapatkan nomor acak di kisaran 1 ... 2. Saya mengambil ide dari sini . Untuk mengatur bit 9 tinggi, saya menggunakan beberapa bit-mengutak-atik 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

Untuk menghasilkan dua angka acak, saya menggunakan loop bersarang dari 2 iterasi. Saya mengaturnya dengan xor:

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

Kode floating-point mengimplementasikan transformasi Box-Muller .


2

Haskell, 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

Contoh penggunaan:

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

Tipe kembalinya randomdibatasi Float, yang membuat randommenghasilkan float yang seragam dalam [0, 1). Sejak saat itu, ini adalah formula box-muller simlpe dengan sihir tak berguna untuk pembuatan daftar.


2

Golflua, 63 70

Info dan instruksi Golflua.

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

Mengembalikan tabel yang berisi nilai-nilai. Dalam contoh yang saya gunakan ~T.u( ), yang sama dengan return table.unpack( )di 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

Banyak karakter disimpan dengan mengatur lingkungan fungsi ke M(alias math).


2

SAS, 108

Saya sudah memposting jawaban dalam R yang lebih pendek dari ini, tetapi ada sangat sedikit jawaban SAS di PPCG, jadi mengapa tidak menambahkan yang lain?

%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;

Dengan sedikit ruang putih:

%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;

Ini mendefinisikan makro yang bisa disebut seperti %f(5, 3). Makro mengeksekusi langkah data yang loop melalui bilangan bulat 1 ke N, dan pada setiap iterasi menghitung penyimpangan normal acak menggunakan Box-Muller dan mencetaknya ke log menggunakan putpernyataan.

SAS tidak memiliki built-in untuk pi, jadi yang terbaik yang bisa kita lakukan adalah memperkirakannya dengan arctangent.

The ranuni()function (yang sudah ditinggalkan tetapi membutuhkan pasangan karakter yang lebih sedikit daripada fungsi baru) mengembalikan nomor acak dari distribusi seragam. Dokumentasi SAS tidak memberikan banyak detail tentang implementasi RNG selain memiliki periode 2 ^ 31-2.

Dalam makro SAS, variabel makro direferensikan dengan sebelumnya &dan menyelesaikan nilai-nilainya pada saat run time.

Seperti yang mungkin telah Anda saksikan, SAS jarang menjadi lawan yang sebenarnya dalam kontes .


2

Java, 193 byte

Meskipun ini tidak mengalahkan pemimpin Java saat ini, saya memutuskan untuk tetap memposting untuk menunjukkan metode perhitungan yang berbeda. Ini adalah versi OpenJDK dari golf 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;}}

Dengan jeda baris:

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 untuk menggunakan Marsaglia (atau lebih tepatnya karena tidak menggunakan Box-Muller lurus-lurus);)
Martin Ender

Bisakah ini bukan lambda? Sesuatu seperti:(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;}
Justin

2
@ Quincunx saya bisa, untuk satu byte. Tapi saya tidak suka menyembunyikan deklarasi fungsi saya dalam kode tak terhitung, apa pun konsensus saat ini tentang meta tentang itu. Layak satu byte untuk saya;)
Geobits

2

T-SQL, 155 byte

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

Gunakan dengan EXEC RS, N karena tidak ada STD_IN di T-SQL di mana S dan N adalah seed dan N masing-masing. S akan menghasilkan urutan "acak" (RAND (seed) adalah implementasi angka acak yang benar-benar buruk) ketika S> 2 ^ 16 (mungkin sebelum itu, tetapi saya tidak akan menjaminnya). Menggunakan Box-Muller seperti kebanyakan solusi sejauh ini. 8388607 adalah 2 ^ 23-1, yang diharapkan akan menghasilkan 2 ^ 20 nilai yang berbeda.


2

Powershell, 164 byte

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

Sama seperti kebanyakan jawaban dengan Box-Muller. Tidak terlalu berpengalaman dengan Powershell, sehingga bantuan golf apa pun akan dihargai.


2

Ruby, 72 byte

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

Input (sebagai fungsi lambda):

f.(6, 12353405)

Keluaran:

-1.1565142460805273
0.9352802655317097
1.3566720571574993
-0.9683973210257978
0.9851210877202192
0.14709635752306677

PS: Saya ingin tahu apakah ini bisa golf lebih lanjut. Saya hanya seorang pemula.


@ MartinBüttner Saya pikir saya sudah menggunakan terlalu banyak C hari ini. Benar-benar lupa.
Zero Fiber

2

Matlab, 77

Input pertama harus n, input kedua s.

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

2

Oktaf, 91 96 88 byte

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

Atau, dengan spasi putih:

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

Atur benih di depan, dan gunakan metode Box-Mueller.

NB: Oktaf memungkinkan untuk menghasilkan array angka acak, dan dapat menggunakan operasi standar pada array ini yang menghasilkan output array. The .*operator adalah elemen-by-elemen perkalian dua array untuk menghasilkan hasil.


Saya pikir ini tidak memenuhi persyaratan, jika Anda menelepon n(0,1)dan n(0,2)mendapatkan nomor pertama yang berbeda, bukan?
flawr

Sial, kau benar. Saya sudah memperbaikinya tetapi harganya 5 byte ...
dcsohl

2

Pyth, 32 byte

Tidak ada Python yang digunakan sekarang dalam tanda kutip super karena fungsi baru yang dimiliki Pyth sekarang. Namun Box-Mueller yang lain.

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

Ruang pada awalnya itu penting.

.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

Penyemaian tampaknya tidak berfungsi dalam penerjemah online, tetapi berfungsi dengan baik dalam versi lokal. Penerjemah online tampaknya sudah diperbaiki, jadi inilah permalink: permalink


1
Ini menggunakan fitur Pyth ( .nZ) yang tidak diterapkan, ketika pertanyaan diajukan. (Ini sebenarnya diterapkan hari ini.) Oleh karena itu jawaban ini tidak boleh menjadi bagian dari kompetisi ( meta.codegolf.stackexchange.com/questions/4867/… ).
Jakube

K, saya akan kembali ke solusi 32 char
Maltysen

Ya, itu akan lebih baik. Anda masih dapat memamerkan solusi baru di bagian terpisah dari jawaban Anda. Tetapi kode pesaing Anda haruslah yang bekerja dengan Pyth yang lama.
Jakube

1
Btw, saya tidak berpikir bahwa solusi 32 harus valid juga. Karena menggunakan benih acak diinisialisasi, yang hanya ditambahkan sekitar 5 hari yang lalu.
Jakube

1

STATA, 85 byte

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

Mengambil input melalui standar dalam (angka pertama adalah S, lalu N). Atur seed menjadi S. Atur jumlah pengamatan ke N. Membuat variabel dan set nilainya ke nilai transformasi Box Muller (terima kasih kepada @Alex untuk menunjukkannya). Kemudian daftarkan semua pengamatan dalam sebuah tabel dengan tajuk kolom a dan angka-angka pengamatan di sebelahnya. Jika ini tidak apa-apa, beri tahu saya, dan saya bisa menghapus header dan / atau nomor observasi.


1

R, 89 Bytes

Saya tahu R telah dilakukan sebelumnya tetapi saya ingin menunjukkan pendekatan yang berbeda dari Box-Muller yang digunakan orang lain. Solusi saya menggunakan Teorema Limit Pusat .

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

1
Saya khawatir, teorema limit pusat tidak memuaskan "algoritma yang Anda pilih harus menghasilkan distribusi normal yang tepat secara teoritis". Tidak peduli berapa banyak variabel seragam yang Anda tambahkan, selama jumlahnya terbatas, distribusi normal akan selalu merupakan perkiraan. (Walaupun teorema limit pusat adalah ide yang bagus, saya harus mengesampingkannya secara tepat karena tidak jelas nilai mana yang harus digunakan adalam kode Anda sehingga hasilnya "adil".)
Martin Ender

1
Itu layak dicoba;)
Michal

1

TI-Basic, 74 byte

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

The ¹sebenarnya operator terbalik.


1

Perl, 150 108 107 byte

Ini menggunakan Metode Kutub Marsaglia . Disebut dengan f (S, N).

Pindah tugas $ake dalam perhitungan $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]}

Penyimpanan nomor cadangan yang dihapus dan definisi $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

Tidak ada yang pintar, hanya melihat cara kerja Swift.

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

Saya berharap saya bisa menggunakan (0 ... n) .map {} tetapi kompilernya sepertinya tidak mengenali peta {} kecuali Anda menggunakan parameter.


tentu saja...? ituforEach jika Anda tidak ingin nilai kembali, dan saya cukup yakin _ inini wajib
ASCII-saja

untuk apa /0xffffffffbtw
ASCII

1

Haskell , 97 byte

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

Cobalah online!

Hanya transformasi Box-Muller dasar Anda, pada daftar angka acak tanpa batas.



0

SmileBASIC, 81 byte

Nah, sekarang saya sudah menjawab pertanyaan pertama, saya harus melakukan semua yang lain ...

Menghasilkan angka acak itu murah, tetapi menyemai RNG menggunakan fungsi builtin terpanjang dalam bahasa RANDOMIZE,.

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

Mungkin ada beberapa cara untuk mengoptimalkan formula. Saya tidak melihat bagaimana diperlukan untuk menggunakan dua panggilan RNG.


Hal ini diperlukan untuk memiliki dua sampel independen untuk transformasi Box-Muller
ASCII-satunya
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.