Günün Rastgele Golf # 2: Normal Dağılımdan Sayılar


12

Seri Hakkında

Öncelikle, bunu diğer kod golf zorlukları gibi ele alabilir ve seri hakkında endişelenmeden cevaplayabilirsiniz. Ancak, tüm zorluklarda bir lider tablosu vardır. Liderlik tablosunu, diziyle ilgili daha fazla bilgiyi ilk gönderide bulabilirsiniz .

Dizi için sıralanmış bir sürü fikrim olmasına rağmen, gelecekteki zorluklar henüz taş değil. Herhangi bir öneriniz varsa, lütfen ilgili sandbox gönderisinde bana bildirin .

Delik 2: Normal Dağılımdan Sayılar

Bunun henüz yapılmadığına inanamıyorum! Normal bir dağılımdan rastgele sayılar üreteceksiniz . Bazı kurallar (bunların çoğu muhtemelen çoğu gönderimle otomatik olarak kapsanır, ancak bazıları çok farklı diller arasındaki sonuçların tutarlılığını sağlamak için mevcuttur):

  • Girdi olarak negatif olmayan iki tamsayı almalısınız : bir tohum Sve Ndöndürülecek sayı miktarı . Çıktı N, ortalama 0 ve varyans 1 ile normal bir dağılımdan çizilmiş kayan nokta sayılarının bir listesi olmalıdır . Gönderiniz aynı tohum verildiğinde Saynı numarayı üretmelidir. Özellikle, bir kez ve bir kez ile çağrılırsa , iki çıkışın ilk girişleri aynı olmalıdır. Ek olarak, en az 2116 farklı değer farklı diziler üretmelidir.(S, N1)(S, N2)min(N1, N2)S

  • En az 2 16 farklı tohumu desteklemesi şartıyla, (yaklaşık) tekdüze bir dağılımdan sayı çizmek için belgelenmiş herhangi bir yerleşik rasgele sayı üretecini kullanabilirsiniz . Bunu yaparsanız , RNG sizden talep ettiğiniz herhangi bir sayı için en az 20 20 farklı değer döndürebilmelidir .S

  • Mevcut tek tip RNG'niz daha küçük bir aralığa sahipse, göremiyorsanız veya çok az sayıda tohum destekliyorsa, önce yerleşik olanın üzerine yeterince geniş bir aralığa sahip tek tip bir RNG oluşturmalısınız veya kullanarak kendi uygun RNG'nizi uygulamalısınız. tohum. Bu sayfa bunun için yararlı olabilir.
  • Normal dağılımlar oluşturmak için yerleşik bir algoritma uygulamıyorsanız, lütfen bir doğruluk kanıtı ekleyin. Her iki durumda da, seçtiğiniz algoritmanın teorik olarak kesin bir normal dağılım (temel PRNG'nin veya sınırlı hassasiyetli veri türlerinin engelleme sınırlamaları) vermesi gerekir .
  • Uygulamanız kayan noktalı sayıları (en az 32 bit genişliğinde) veya sabit noktalı sayıları (en az 24 bit genişliğinde) kullanmalı ve döndürmelidir ve tüm aritmetik işlemler seçilen türün tam genişliğini kullanmalıdır.
  • Doğrudan normal dağılımla veya Hata işlevi veya tersi gibi Gauss integralleri ile ilişkili yerleşik işlevleri kullanmamalısınız .

Tam bir program veya işlev yazabilir ve STDIN, komut satırı bağımsız değişkeni, işlev bağımsız değişkeni veya istemi yoluyla girdi alabilir ve dönüş değeri veya STDOUT (veya en yakın alternatif) ile çıktı oluşturabilirsiniz.

Sve Nnegatif olmayan tamsayılar olacak, her biri 2 20'den küçük olacak . Çıktı herhangi bir uygun, anlaşılır liste veya dize biçiminde olabilir.

Bu kod golf, yani en kısa gönderme (bayt cinsinden) kazanır. Ve elbette, kullanıcı başına en kısa gönderim de serinin genel skor tablosuna girecektir.

Liderler Sıralaması

Serinin ilk yazısı bir skor tablosu oluşturur.

Yanıtlarınızın göründüğünden emin olmak için, lütfen aşağıdaki Markdown şablonunu kullanarak her cevaba bir başlık ile başlayın:

# Language Name, N bytes

Ngönderiminizin büyüklüğü nerede . Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

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

(Dil şu anda gösterilmiyor, ancak snippet gerektiriyor ve ayrıştırıyor ve gelecekte bir dil lider tablosu ekleyebilirim.)


Bekle, tamsayı olmayan aralıklı RNG'leri kullanmamıza izin var mı?
mniip

PS 2 mevcut cevaplar [0, 1) kayan noktalı RNG'ler kullanıyor gibi görünüyor, buna izin veriliyor mu?
mniip

mniip Evet, tekdüze, görülebilir ve gerekli sayıda farklı şamandıra döndürebilmeleri koşuluyla kayan noktalı RNG'lere izin verilir.
Martin Ender

Yanıtlar:


8

Dyalog APL, 33 bayt

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

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

Bunun başka bir dil tarafından yenemeyeceğinden eminim.
Zero Fiber

2
Bu şu kurala uymuyor: "Özellikle, (S, N1) ile bir kez ve (S, N2) ile bir kez çağrılırsa, iki çıkışın ilk min (N1, N2) girişleri aynı olmalıdır."
marinus

@marinus Teşekkürler, düzeltildi. Ben de değişmiş ⎕rlolması S+1nedeniyle ⎕rl←0özel bir anlamı vardır.
ngn

Muhtemelen aslında ihtiyacınız yoktur +1, tek söylediği tek şey en az 2 ^ 16 farklı değeri desteklemeniz gerektiğidir. Bu nedenle [1..2 ^ 16] aralığında doğru şekilde çalışılması iyi olmalıdır.
marinus

S = 0, hesaplamayı tekrarlanabilir yapmaz, bu da yukarıda alıntıladığınız kuralı ihlal eder.
ngn

8

R, 68 bayt

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

Bu, runif()düzgün bir dağılımdan rastgele sapmalar üreten işlevi kullanır . Rastgele sayı üretimi için tohum set.seed(), varsayılan olarak Mers ^ 2-Twister algoritmasını 2 ^ 19937-1'lik bir periyot ile kullanan belirtilir .

Sonuç, hesaplanan standart normal sapmaları içeren N uzunluğundaki bir R vektörüdür.

Bu, Box-Muller yöntemini kullanır: İki bağımsız tekdüze rastgele değişken U ve V için, resim açıklamasını buraya girin


Bu, R'deki geçerli sözdizimi dışında f=bırakılabilir (adsız işlevler dilinizde bir şeyse, işlevin mutlaka adlandırılması gerekmez).
Martin Ender

@ MartinBüttner: Öneriyi takdir ediyorum ama bilgime göre R isimsiz bir fonksiyonla ne yapacağını bilemezdi.
Alex A.

Ayrıca her zaman bir hata mesajı alıyorum Error: unexpected '}' in "f=fu..., eğer ararsanız aynı ilk numaraları aldığınızdan emin misiniz f(0,1)ve f(0,2)?
flawr

4

Dyalog APL, 42 34

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

Bu, Ssol argümanını ve Nsağ argümanını alan bir işlevdir .

     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'nin yerleşik rasgele işlecini kullanan Box-Muller dönüşümünün bir uygulamasıdır ?, bu da varsayılan olarak yeterli olması gereken 64 bit değerleri döndüren bir Mersenne twister'idir.

Açıklama:

  • ⎕RL←⍺: rastgele tohumu olarak ayarlayın .
  • ?⍵2⍴0: 0 ile 1 arasında rastgele sayı çiftleri oluşturur .
  • {... }/: her bir çifte aşağıdaki işlevi uygular:
    • (.5*⍨¯2×⍟⍺)×1○⍵×○2: Z0değeri hesaplar ( sqrt(-2 ln ⍺)×cos(2π⍵)).

1
V14.0 olarak ?0geri döner, 0 ile 1 arasında bir kayan nokta sayısı
ngn

3

Perl, 67

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

Diğer kayıtlarda olduğu gibi Box-Muller. fparametreleri sırayla alır S, N.

kullanı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 bayt

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

Bu fonksiyon üzerinden giriş ve çıkış stdout yoluyla alır. Box-Muller yöntemini kullanır.


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

1
@Geobits Lambda gibi görünüyor: D
TheNumberOne

3

Commodore 64 Basic, 76 70 63 bayt

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

PETSCII karakter kümesi Unicode'da bulunmayan bazı semboller içerdiğinden, yerine koydum: /= SHIFT+N, = SHIFT+O, = SHIFT+Q, = SHIFT+I, =SHIFT+E

Bu, sayıları oluşturmak için standart Box-Muller dönüşümünü uygular; Dönüşümün günah (x) yarısını seçtim çünkü Commodore 64 Basic için iki karakterli bir kısayol var sin(), ama değil cos().

Aksi manuel belirtse de, argüman değeri RND yok olsun: negatif bir sayı aktarılırsa, rasgele sayı üreteci sadece tohumlanmamış yeniden değil, yeniden ekilir bu numara ile . Bu, tohumlamayı çok daha basit hale getirir: POKEbeş bellek konumuna ihtiyaç duymak yerine, sadece RNDiki satır / 121 bayttan 1 satıra / 76 bayta kadar kodu azaltan bir şey yapma çağrısı yapmam gerekiyor .

Düzenleme: Ben iki INPUTifade birleştirebilir ve sonra alan TOisteğe bağlı olduğunu fark ederek altı bayt kapalı Golf .

Düzenleme: Yedi başka bir golf: Commodore Basic, aslında, yerleşik bir sabit olarak Pi var ve hatta modern bir klavyede bile yazılabilir ( SHIFT+PgDnmerak ediyorsanız).


3

80386 makine kodu, 72 bayt

Onaltılık kod:

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

İşte kaynak kodu (Visual Studio tarafından derlenebilir):

__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;
    }
}

Burada bir Lehmer rastgele sayı üreteci kullanıyorum . Aşağıdaki algoritmayı kullanır:

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

Burada 4294967291 büyük (2 ^ 32-5) asal sayıdır ve 116, ilkel kökü olan küçük (128'den az; aşağıya bakınız) bir sayıdır . İkili gösterimde sıfırların veya az ya da çok rastgele dağılım gösteren ilkel bir kök seçtim (01110100). Eğer tohum sıfır değilse, bu RNG'nin olası maksimum süresi 4294967290'dır.


Burada kullandığım nispeten küçük sayılar (116 ve 4294967291, -5 olarak da gösterilebilir), leakomut kodlamasından yararlanmama izin veriyor :

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

Sayılar 1 bayta sığabiliyorsa 3 bayta birleştirilir.


Çarpma ve bölme kullanımı edxve eaxçalışma kayıtları olarak, bu yüzden seedişleve ikinci parametreyi yaptım ( fastcallçağrı kuralı edxikinci parametreyi geçmek için kullanır ). Buna ek olarak, ecxbir sayaç tutmak için iyi bir yer olan ilk parametre iletilir : 1 talimatta bir döngü düzenlenebilir!

e2 c6        loop myloop

Bir tamsayıyı kayan noktalı sayıya dönüştürmek için, tek duyarlıklı kayan noktalı sayıların gösterimini kullandım: yüksek 9 biti (üs) bit desenine ayarlarsam 001111111ve 23 düşük biti rastgele bırakırsam, 1 ... 2 aralığında rastgele bir sayı elde edin. Fikri buradan aldım . Yüksek 9 biti ayarlamak için, biraz bitkince kullandım 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

İki rastgele sayı üretmek için, 2 yinelemeli iç içe bir döngü kullandım. Şununla organize ettim xor:

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

Kayan nokta kodu Box-Muller dönüşümünü uygular .


2

Haskell,  118144 

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

Örnek kullanım:

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

Geri dönüş tipi randomkısıtlanır Float, bu da random[0, 1) 'de düzgün bir şamandıra oluşturur. O andan itibaren liste oluşturma için anlamsız bir sihir içeren bir kutu-muller formülü.


2

Golflua, 63 70

Golflua bilgi ve talimatları.

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

Değerleri içeren bir tablo döndürür. Kullandığım örnekte lua ile ~T.u( )aynı return table.unpack( ).

> ~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

Fonksiyonun çevresini M(aka math) olarak ayarlayarak birçok karakter kaydedildi .


2

SAS, 108

Zaten R'de bundan daha kısa bir cevap gönderdim , ancak PPCG'de çok az SAS cevabı var, neden başka bir tane eklemiyorsunuz?

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

Biraz beyaz boşlukla:

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

Bu, şöyle adlandırılabilecek bir makro tanımlar %f(5, 3). Makro, 1'den N'ye tamsayılar arasında geçiş yapan bir veri adımı yürütür ve her yinelemede Box-Muller kullanarak rastgele bir normal sapma hesaplar ve putifadeyi kullanarak günlüğe yazdırır .

SAS'ın pi için yerleşik bir özelliği yoktur, bu yüzden yapabileceğimiz en iyi şey arktanjant ile yaklaşıktır.

ranuni()(Kaldırıldı ama bir çift yeni fonksiyonu daha az sayıda karakter gerektirir) işlevi tek bir şekilde dağılımı ile ilgili bir rasgele sayı döndürür. SAS belgeleri, 2 ^ 31-2 süresi dışında RNG uygulaması hakkında çok fazla ayrıntı vermez.

SAS makrolarında, makro değişkenlere öncekiyle başvurulur &ve çalışma zamanında değerlerine çözümlenir.

Muhtemelen tanık olduğunuz gibi, SAS nadiren bir yarışmasında gerçek bir yarışmacıdır .


2

Java, 193 bayt

Bu, mevcut Java liderini geçmezken, farklı bir hesaplama yöntemi göstermek için yine de yayınlamaya karar verdim. OpenJDK'ların golf versiyonudur 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;}}

Satır kesmeleri ile:

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
Marsaglia'yı kullanmak için +1 (veya daha doğrusu Box-Muller'ı kullanmamak için);)
Martin Ender

Bu bir lambda olamaz mı? Gibi bir şey:(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 Bir bayt için yapabilirdim. Ama bu konuda meta üzerinde mevcut fikir birliği ne olursa olsun, fonksiyon beyanlarımı sayılmamış kodda saklamayı sevmiyorum. Bana bir bayt değerinde;)
Geobits

2

T-SQL, 155 bayt

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

EXEC RS, N ile kullanın, çünkü S ve N sırasıyla tohum ve N olan T-SQL'de STD_IN yoktur. S, "rastgele" (RAND (tohum) gerçekten kötü bir rasgele sayı uygulaması) dizileri üretecektir (> muhtemelen bundan önce, ama bunu garanti etmeyeceğim). Box-Muller'ı şimdiye kadarki çoğu çözüm gibi kullanıyor. 8388607, 2 ^ 23-1'dir ve umarım 2 ^ 20 farklı değer üretmelidir.


2

Powershell, 164 bayt

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 ile çoğu cevapla aynı. Powershell ile çok deneyimli değil, bu yüzden golf herhangi bir yardım mutluluk duyacağız.


2

Yakut, 72 bayt

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

Giriş (lambda fonksiyonu olarak):

f.(6, 12353405)

Çıktı:

-1.1565142460805273
0.9352802655317097
1.3566720571574993
-0.9683973210257978
0.9851210877202192
0.14709635752306677

Not: Bunun daha fazla golf yapıp yapamayacağını bilmek istiyorum. Ben sadece bir acemiyim.


@ MartinBüttner Sanırım bugünlerde çok fazla C kullanıyorum. Tamamen unutmuşum.
Zero Fiber

2

Matlab, 77

İlk girdi n, ikincisi olmalıdır s.

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

2

Oktav, 91 96 88 bayt

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

Veya boşlukla:

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

Tohumu ön tarafa yerleştirin ve Box-Mueller yöntemini kullanın.

Not: Octave rastgele sayı dizilerinin oluşturulmasına izin verir ve dizi çıktıları üreten bu dizilerde standart işlemleri kullanabilir. .*Operatör sonucu elde etmek için iki dizinin elemanı elemana çoğalmasıdır.


Bence bu şartlara uymuyor, eğer ararsanız n(0,1)ve n(0,2)farklı ilk numaralar alırsanız, değil mi?
flawr

Lanet olsun, haklısın.
Sabitledim

2

Pyth, 32 bayt

Pyth'in sahip olduğu yeni işlevler nedeniyle artık süper tırnaklarda hiçbir Python kullanılmıyor. Yine başka bir Box-Mueller.

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

Başlangıçta bu alan önemlidir.

.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

Tohumlama çevrimiçi yorumlayıcıda çalışmıyor gibi görünüyor, ancak yerel sürümde iyi çalışıyor. Çevrimiçi yorumlayıcı sabit gibi görünüyor, bu yüzden bir kalıcı bağlantı: kalıcı bağlantı


1
Bu .nZ, soru sorulduğunda uygulanmayan bir Pyth ( ) özelliğini kullanır . (Aslında bugün uygulanmıştır.) Bu nedenle bu cevap yarışmanın bir parçası olmamalıdır ( meta.codegolf.stackexchange.com/questions/4867/… ).
Jakube

K, 32 karakterlik çözüme geri döneceğim
Maltysen

Evet, bu daha iyi olurdu. Yine de cevapladığınız ayrı bir bölümde size yeni bir çözüm gösterebilirsiniz. Ancak yarıştığınız kod eski Pyth ile çalışan kod olmalıdır.
Jakube

1
Btw, 32 çözümünün de geçerli olması gerektiğini düşünmüyorum. Başlatılmış rastgele tohum kullandığından, yaklaşık 5 gün önce eklenmiştir.
Jakube

1

STATA, 85 bayt

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

Girişi standart olarak alır (ilk sayı S, sonra N'dir). Çekirdeği S olarak ayarlar. Gözlem sayısını N olarak ayarlar. Bir değişken oluşturur ve değerini Box Muller dönüşüm değerine ayarlar (göstermek için @Alex sayesinde). Daha sonra, tüm gözlemleri sütun başlığı a ve yanında gözlem numaraları bulunan bir tabloda listeler. Bunlar iyi değilse, bana bildirin ve başlıkları ve / veya gözlem numaralarını kaldırabilirim.


1

R, 89 Bayt

R'nin daha önce yapıldığını biliyorum ama herkesin kullandığı Box-Muller'dan farklı bir yaklaşım göstermek istedim. Benim çözümüm Merkezi Limit Teoremini kullanıyor .

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

1
Korkarım, merkezi limit teoremi "seçtiğiniz algoritmanın teorik olarak kesin bir normal dağılım vermesi gerekir" ifadesini karşılamıyor. Kaç tane eşit değişken eklediğiniz önemli değil, toplam sonlu olduğu sürece, normal dağılım her zaman yaklaşık olacaktır. (Merkezi limit teoremi iyi bir fikir olsa da, kesin olarak dışlamak zorunda kaldım, çünkü akodunuzda hangi değerin kullanılması gerektiği net değil çünkü sonuç "adil" olacak.)
Martin Ender

1
Michal

1

TI-Basic, 74 bayt

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

¹Aslında ters operatörüdür.


1

Perl, 150 108 107 bayt

Bu Marsaglia Polar Metodunu kullanır . F (S, N) ile çağrılır.

Atama taşındı $ahesaplanmasında içine $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]}

Kaldırılan yedek parça deposu ve tanımı $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

Akıllıca bir şey yok, sadece Swift'in nasıl çalıştığını görmek.

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

(0 ... n) .map {} kullanabileceğimi umuyordum, ancak bir parametre kullanmadığınız sürece derleyici haritayı tanımıyor gibi görünüyor {}.


elbette...? öyleforEach bir dönüş değeri istemiyorsanız, ben eminim _ inzorunludur
ASCII sadece

/0xffffffffbtw için ne var
sadece ASCII sadece

1

Haskell , 97 bayt

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

Çevrimiçi deneyin!

Rasgele sayıların sonsuz bir listesinde sadece temel Box-Muller dönüşümünüz.



0

SmileBASIC, 81 bayt

Şimdi ilk soruyu cevapladığım için, gerisini yapmak zorundayım ...

Rastgele sayılar üretmek ucuzdur, ancak RNG tohumlama , dilde en uzun yerleşik işlevi kullanır RANDOMIZE.

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

Belki formülü optimize etmenin bir yolu var. İki RNG çağrısı kullanmanın nasıl gerekli olduğunu anlamıyorum.


Edilir Box-Muller dönüşüm için iki bağımsız numune olması gerekir
ASCII sadece
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.