Random Golf of the Day # 2: Numbers from a Normal Distribution


12

O serii

Po pierwsze, możesz potraktować to jak każde inne wyzwanie związane z golfem i odpowiedzieć na nie, nie martwiąc się w ogóle serią. Istnieje jednak tabela wyników dla wszystkich wyzwań. Możesz znaleźć tabelę liderów wraz z kilkoma więcej informacji o serii w pierwszym poście .

Chociaż mam szereg pomysłów w szeregu, przyszłe wyzwania nie są jeszcze ustalone. Jeśli masz jakieś sugestie, daj mi znać w odpowiednim poście z piaskownicą .

Otwór 2: Liczby z rozkładu normalnego

Nie mogę uwierzyć, że jeszcze tego nie zrobiono! Masz generować liczby losowe, czerpiąc z normalnego rozkładu . Niektóre reguły (większość z nich jest prawdopodobnie automatycznie objęta większością zgłoszeń, ale niektóre z nich istnieją, aby zapewnić spójność wyników w bardzo różnych językach):

  • Powinieneś wziąć dwie nieujemne liczby całkowite jako dane wejściowe : ziarno Si liczbę Nliczb do zwrócenia. Wyjściem powinna być lista Nliczb zmiennoprzecinkowych, sporządzona z rozkładu normalnego ze średnią 0 i wariancją 1 . Ilekroć twoje zgłoszenie otrzyma to samo ziarno S, powinno ono dać ten sam numer. W szczególności, jeśli zostanie wywołany raz z i raz z , pierwsze wpisy dwóch wyjść powinny być identyczne. Ponadto co najmniej 2 16 różnych wartości powinno dawać różne sekwencje.(S, N1)(S, N2)min(N1, N2)S

  • Możesz użyć dowolnego wbudowanego generatora liczb losowych, który jest udokumentowany, aby rysować liczby z (w przybliżeniu) równomiernego rozkładu, pod warunkiem, że możesz to przekazać Si obsługuje on co najmniej 2 16 różnych nasion. Jeśli to zrobisz, RNG powinien mieć możliwość zwrócenia co najmniej 2 20 różnych wartości dla dowolnej liczby, o którą prosisz.

  • Jeśli dostępny jednolity RNG ma mniejszy zasięg, nie nadaje się do wysiewu lub obsługuje zbyt mało nasion, musisz albo najpierw zbudować jednolity RNG o wystarczająco dużym zasięgu na wbudowanym, albo musisz zaimplementować własny odpowiedni RNG za pomocą nasiono. Ta strona może być do tego pomocna.
  • Jeśli nie wdrożysz ustalonego algorytmu generowania normalnych rozkładów, dołącz dowód poprawności. W obu przypadkach wybrany algorytm musi dawać teoretycznie dokładny rozkład normalny (ograniczenia blokujące leżące u podstaw PRNG lub typy danych o ograniczonej precyzji).
  • Twoja implementacja powinna używać i zwracać albo liczby zmiennoprzecinkowe (o szerokości co najmniej 32 bity), albo liczby o stałym punkcie (o szerokości co najmniej 24 bity), a wszystkie operacje arytmetyczne powinny wykorzystywać pełną szerokość wybranego typu.
  • Nie wolno używać żadnych wbudowanych funkcji bezpośrednio związanych z rozkładem normalnym lub całkami Gaussa, takich jak funkcja Błąd lub jej odwrotność.

Możesz napisać pełny program lub funkcję i pobrać dane wejściowe za pomocą STDIN, argumentu wiersza poleceń, argumentu funkcji lub pytania i wygenerować dane wyjściowe za pomocą wartości zwracanej lub drukując do STDOUT (lub najbliższej alternatywy).

Si Nbędą liczbami całkowitymi nieujemnymi, każda mniejsza niż 2 20 . Dane wyjściowe mogą być w dowolnym wygodnym, jednoznacznym formacie listy lub ciągu.

To jest kod golfowy, więc wygrywa najkrótsze przesłanie (w bajtach). I oczywiście najkrótsze zgłoszenie na użytkownika wejdzie również do ogólnej tabeli liderów serii.

Tabela liderów

Pierwszy post z serii generuje tabelę wyników.

Aby mieć pewność, że Twoje odpowiedzi się pojawią, zacznij każdą odpowiedź od nagłówka, używając następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

(Język nie jest obecnie wyświetlany, ale fragment go wymaga i analizuje, a w przyszłości mogę dodać tabelę wyników według języków).


Chwila, czy wolno nam używać RNG z zakresu niecałkowitego?
mniip

Wydaje się, że istniejące odpowiedzi PS 2 wykorzystują zmiennoprzecinkowe RNG, czy to jest dozwolone?
mniip

@mniip Tak, zmiennoprzecinkowe RNG są dozwolone, pod warunkiem, że są jednorodne, można je wysiać i mogą zwrócić wymaganą liczbę odrębnych pływaków.
Martin Ender,

Odpowiedzi:


8

Dyalog APL, 33 bajty

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

Jestem prawie pewien, że nie da się tego pokonać żadnym innym językiem.
Zero Fibre

2
To nie spełnia tej zasady: „W szczególności, jeśli zostanie wywołany raz z (S, N1) i raz z (S, N2), pierwsze wpisy min (N1, N2) dwóch wyjść powinny być identyczne.”
marinus

@marinus Dzięki, naprawiono. Zmieniłem się również ⎕rlna, S+1ponieważ ⎕rl←0ma specjalne znaczenie.
ngn

Prawdopodobnie tak naprawdę nie potrzebujesz +1, wszystko mówi, że musisz obsługiwać co najmniej 2 ^ 16 różnych wartości. Więc poprawne działanie w zakresie [1..2 ^ 16] powinno być OK.
marinus

S = 0 spowodowałoby, że obliczenia nie byłyby powtarzalne, co naruszałoby regułę cytowaną powyżej.
ngn

8

R, 68 bajtów

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

Wykorzystuje to runif()funkcję, która generuje losowe odchylenia od jednolitego rozkładu. Ziarno do generowania liczb losowych jest określane za pomocą set.seed(), który domyślnie wykorzystuje algorytm Mersenne-Twister z okresem 2 ^ 19937-1.

Wynikiem jest wektor R o długości N zawierający obliczone standardowe odchylenie normalne.

Wykorzystuje to metodę Boxa-Mullera: dla dwóch niezależnych jednorodnych zmiennych losowych U i V, wprowadź opis zdjęcia tutaj


Jeśli jest to poprawna składnia w R, możesz pominąć f=(funkcja niekoniecznie musi być nazwana, jeśli funkcje nienazwane są w twoim języku).
Martin Ender,

@ MartinBüttner: Doceniam sugestię, ale o ile wiem, R nie wiedziałby, co zrobić z nienazwaną funkcją.
Alex A.,

Error: unexpected '}' in "f=fu...Poza tym zawsze pojawia się komunikat o błędzie. Czy na pewno otrzymasz te same pierwsze numery, jeśli zadzwonisz f(0,1)i f(0,2)?
flawr

4

Dyalog APL, 42 34

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

Jest to funkcja, która przyjmuje Sza lewy argument i Nza prawy argument.

     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

Jest to implementacja transformacji Box-Muller, wykorzystująca wbudowany losowy operator Dyalog APL ?, który domyślnie jest twisterem Mersenne, który zwraca 64-bitowe wartości, co powinno wystarczyć.

Wyjaśnienie:

  • ⎕RL←⍺: ustaw losowe ziarno na .
  • ?⍵2⍴0: generuj pary liczb losowych od 0 do 1.
  • {... }/: zastosuj następującą funkcję do każdej pary:
    • (.5*⍨¯2×⍟⍺)×1○⍵×○2: oblicz Z0wartość ( sqrt(-2 ln ⍺)×cos(2π⍵)).

1
W wersji 14.0 ?0zwraca liczbę zmiennoprzecinkową między 0 a 1.
ngn

3

Perl, 67

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

Box-Muller jak w innych wpisach. fporządkuje parametry S, N.

Posługiwać się:

$ 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 bajtów

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

To pobiera dane wejściowe za pomocą funkcji i dane wyjściowe za pośrednictwem standardowego wyjścia. Wykorzystuje metodę Box-Mullera.


5
s=0;s++<n;-> ;n-->0;?
Geobity,

1
@Geobits Wygląda jak lambda: D
TheNumberOne

3

Commodore 64 Basic, 76 70 63 bajtów

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

Ponieważ zestaw znaków PETSCII zawiera pewne symbole, które nie są obecne w Unicode, zrobiłem podstawienia: /= SHIFT+N, = SHIFT+O, = SHIFT+Q, = SHIFT+I, =SHIFT+E

To implementuje standardową transformację Boxa-Mullera do generowania liczb; Wybrałem połowę transformacji sin (x), ponieważ Commodore 64 Basic ma dwuznakowy skrót do sin(), ale nie do cos().

Chociaż instrukcja mówi inaczej, wartość argumentu RND ma znaczenie: jeśli liczba ujemna zostanie przekazana, generator liczb losowych nie jest po prostu ponownie inicjowany, jest on ponownie inicjowany z tą liczbą . To sprawia, że ​​inicjowanie jest znacznie prostsze: zamiast potrzebować POKEpięciu lokalizacji w pamięci, po prostu muszę wywołać polecenie „nic nie rób” RND, co zmniejsza kod z dwóch linii / 121 bajtów do 1 linii / 76 bajtów.

Edycja: Grałem w golfa o sześć bajtów, zdając sobie sprawę, że mogę połączyć te dwie INPUTwypowiedzi i że miejsce po TOjest opcjonalne.

Edycja: Grałem w golfa o kolejne siedem: Commodore Basic ma Pi jako wbudowaną stałą, a nawet można go pisać na nowoczesnej klawiaturze ( SHIFT+PgDnna wypadek, gdybyś się zastanawiał).


3

Kod maszynowy 80386, 72 bajty

Hexdump kodu:

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

Oto kod źródłowy (może zostać skompilowany przez 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;
    }
}

Tutaj używam generatora liczb losowych Lehmera . Wykorzystuje następujący algorytm:

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

Tutaj 4294967291 jest dużą (2 ^ 32-5) liczbą pierwszą, a 116 jest małą (mniej niż 128; patrz poniżej) liczbą, która jest jej pierwotnym pierwiastkiem . Wybrałem pierwotny katalog główny, który ma mniej więcej losowy rozkład zer i jedynek w reprezentacji binarnej (01110100). Ten RNG ma maksymalny możliwy okres 4294967290, jeśli ziarno jest niezerowe.


Stosunkowo małe liczby, których tu użyłem (116 i 4294967291, które można również przedstawić jako -5), pozwalają mi skorzystać z leakodowania instrukcji:

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

Składa się z 3 bajtów, jeśli liczby mieszczą się w 1 bajcie.


Wykorzystanie mnożenia i dzielenia edxoraz eaxich rejestrów roboczych, dlatego wprowadziłem seeddrugi parametr do funkcji ( fastcallkonwencja wywoływania używa edxdo przekazania drugiego parametru). Ponadto przekazywany jest pierwszy parametr ecx, który jest dobrym miejscem do przechowywania licznika: pętla może być zorganizowana w 1 instrukcji!

e2 c6        loop myloop

Aby przekonwertować liczbę całkowitą na liczbę zmiennoprzecinkową, wykorzystałem reprezentację liczb zmiennoprzecinkowych o pojedynczej precyzji: jeśli ustawię wysokie 9 bitów (wykładnik) na wzór bitowy 001111111i pozostawię 23 niskie bity losowe, uzyskaj losową liczbę z zakresu 1 ... 2. Stąd pomysł . Aby ustawić wysokie 9 bitów, użyłem trochę bicia na 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

Aby wygenerować dwie liczby losowe, użyłem zagnieżdżonej pętli 2 iteracji. Zorganizowałem to z xor:

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

Kod zmiennoprzecinkowy implementuje transformację 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

Przykładowe użycie:

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

Zwracany jest typ zwracany randomdo Float, co powoduje, że randomgenerowanie jednolitego zmiennoprzecinkowego w [0, 1). Od tego czasu jest to prosta formuła box-muller z pewną bezcelową magią do generowania list.


2

Golflua, 63 70

Informacje i instrukcje Golflua.

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

Zwraca tabelę zawierającą wartości. W przykładzie używam ~T.u( ), który jest taki sam jak return table.unpack( )w 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

Wiele znaków zostało zapisanych przez ustawienie środowiska funkcji na M(aka math).


2

SAS, 108

Już opublikowałem odpowiedź w R, która jest krótsza niż ta, ale na PPCG jest bardzo mało odpowiedzi SAS, więc dlaczego nie dodać kolejnej?

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

Z białą przestrzenią:

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

Definiuje makro, które można nazwać jak %f(5, 3). Makro wykonuje krok danych, który przechodzi przez liczby całkowite od 1 do N, a przy każdej iteracji oblicza losowe odchylenie normalne za pomocą Box-Mullera i drukuje je w dzienniku za pomocą putinstrukcji.

SAS nie ma wbudowanej funkcji pi, więc najlepsze, co możemy zrobić, to przybliżyć ją za pomocą arcus tangens.

ranuni()Funkcji (co jest przestarzałe, ale wymaga Kilka mniej znaków niż nowszych funkcji) zwraca liczbę losową z rozkładu jednorodnego. Dokumentacja SAS nie podaje zbyt wielu szczegółów na temat implementacji RNG poza okresem 2 ^ 31-2.

W makrach SAS makrozmienne są przywoływane za pomocą poprzedzającego &i tłumaczą się na ich wartości w czasie wykonywania.

Jak zapewne zauważyłeś, SAS rzadko jest prawdziwym konkurentem w zawodach .


2

Java, 193 bajty

Chociaż nie jest to w stanie pokonać obecnego lidera Javy, postanowiłem mimo to opublikować inną metodę obliczeń. To wersja OpenJDK dla gry w golfa 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;}}

Z podziałami linii:

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 za użycie Marsaglii (a raczej za nieużywanie prostego Box-Mullera);)
Martin Ender

Czy to nie może być lambda? Coś w stylu:(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 Mógłbym, na jeden bajt. Ale nie lubię ukrywać deklaracji funkcji w niezliczonym kodzie, niezależnie od obecnego konsensusu w sprawie meta. Jest to dla mnie warte jeden bajt;)
Geobits

2

T-SQL, 155 bajtów

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

Użyj z EXEC RS, N, ponieważ nie ma STD_IN w T-SQL, gdzie S i N są odpowiednio ziarnem i N. S wytworzy sekwencje „losowe” (RAND (seed) to naprawdę zła implementacja liczb losowych), gdy S> 2 ^ 16 (być może wcześniej, ale nie będę tego gwarantować). Wykorzystuje Box-Muller jak większość dotychczasowych rozwiązań. 8388607 to 2 ^ 23-1, co, mam nadzieję, powinno wygenerować 2 ^ 20 różnych wartości.


2

PowerShell, 164 bajty

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

Taki sam jak większość odpowiedzi z Box-Muller. Niezbyt doświadczony w Powershell, więc każda pomoc w golfa będzie mile widziana.


2

Rubinowy, 72 bajty

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

Dane wejściowe (jako funkcja lambda):

f.(6, 12353405)

Wynik:

-1.1565142460805273
0.9352802655317097
1.3566720571574993
-0.9683973210257978
0.9851210877202192
0.14709635752306677

PS: Chciałbym wiedzieć, czy można dalej grać w golfa. Jestem tylko początkującym.


@ MartinBüttner Myślę, że ostatnio używam zbyt dużo C. Całkowicie zapomniałem o.
Zero Fibre

2

Matlab, 77

Pierwszym wejściem powinno być ndrugie s.

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

2

Oktawa, 91 96 88 bajtów

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

Lub z białymi znakami:

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

Ustaw ziarno z przodu i użyj metody Boxa-Muellera.

Uwaga: Octave pozwala generować tablice liczb losowych i może używać standardowych operacji na tych tablicach, które generują dane wyjściowe z tablicy. .*Operator mnożenie element po elemencie dwóch matryc do produkcji wynik.


Myślę, że to nie spełnia warunków, jeśli zadzwonisz n(0,1)i n(0,2)otrzymasz różne pierwsze numery, prawda?
flawr

Cholera, masz rację. Naprawiłem to, ale kosztowało mnie to 5 bajtów ...
dcsohl,

2

Pyth, 32 bajty

Żadne Python nie jest teraz używany w super-cytatach z powodu nowych funkcji, które ma teraz Pyth. Jeszcze jeden Box-Mueller.

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

Ta przestrzeń na początku jest ważna.

.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

Ziarno nie wydaje się działać w tłumaczu online, ale działa dobrze w wersji lokalnej. Interpreter online wydaje się być naprawiony, więc oto link bezpośredni: link bezpośredni


1
Korzysta z funkcji Pyth ( .nZ), która nie została zaimplementowana, gdy pytanie zostało zadane. (W rzeczywistości został dzisiaj wdrożony.) Dlatego odpowiedź ta nie powinna być częścią konkursu ( meta.codegolf.stackexchange.com/questions/4867/… ).
Jakube,

K, wrócę do rozwiązania dla 32
znaków

Tak, byłoby lepiej. Nadal możesz pochwalić się nowym rozwiązaniem w osobnej sekcji odpowiedzi. Ale kod, w którym konkurujesz, powinien być tym, który działa ze starym Pythem.
Jakube,

1
Przy okazji, nie sądzę, że 32 rozwiązanie również powinno być poprawne. Ponieważ korzysta z inicjowanego losowego materiału siewnego, który został dodany dopiero około 5 dni temu.
Jakube,

1

STATA, 85 bajtów

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

Pobiera dane wejściowe przez wejście standardowe (pierwsza liczba to S, a następnie N). Ustawia ziarno na S. Ustawia liczbę obserwacji na N. Robi zmienną i ustawia jej wartość na wartość przekształcenia Box Mullera (dzięki @Alex za jej pokazanie). Następnie wypisuje wszystkie obserwacje w tabeli z nagłówkiem kolumny a i numerami obserwacji obok nich. Jeśli nie są w porządku, daj mi znać, a mogę usunąć nagłówki i / lub numery obserwacji.


1

R, 89 bajtów

Wiem, że R zostało już zrobione, ale chciałem pokazać inne podejście niż Box-Muller, którego używali wszyscy inni. Moje rozwiązanie wykorzystuje Twierdzenie Central Limit .

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

1
Obawiam się, że centralne twierdzenie graniczne nie spełnia „wybrany algorytm musi dać teoretycznie dokładny rozkład normalny”. Bez względu na to, ile zsumowanych zmiennych jednolitych dodasz, dopóki suma jest skończona, rozkład normalny zawsze będzie przybliżony. (Chociaż twierdzenie o limicie centralnym jest dobrym pomysłem, musiałem je wykluczyć właśnie dlatego, że nie jest jasne, której wartości należy użyć aw kodzie, aby wynik był „sprawiedliwy”.)
Martin Ender,

1
Warto było spróbować;)
Michał

1

TI-Basic, 74 bajty

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

Jest ¹to w rzeczywistości operator odwrotny.


1

Perl, 150 108 107 bajtów

Wykorzystuje metodę Marsaglia Polar . Wywoływany za pomocą f (S, N).

Przeniesiono przypisanie $ado obliczeń $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]}

Usunięto przechowywanie numerów zapasowych i definicję $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

Nic mądrego, po prostu widząc, jak działa 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))}}

Miałem nadzieję, że mogę użyć (0 ... n) .map {}, ale wydaje się, że kompilator nie rozpoznaje mapy {}, chyba że użyjesz parametru.


oczywiście...? dzieje się tak,forEach jeśli nie chcesz zwracanej wartości, i jestem prawie pewien, że _ injest ona obowiązkowa
tylko ASCII

co /0xffffffffza btw
tylko ASCII

1

Haskell , 97 bajtów

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

Wypróbuj online!

Tylko twoja podstawowa transformacja Boxa-Mullera na nieskończonej liście liczb losowych.



0

SmileBASIC, 81 bajtów

Cóż, teraz, kiedy odpowiedziałem na pierwsze pytanie, muszę zrobić resztę ...

Generowanie liczb losowych jest tani, ale zaszczepienie RNG używa najdłuższy funkcji wbudowanego w języku RANDOMIZE.

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

Może jest jakiś sposób na zoptymalizowanie formuły. Nie rozumiem, jak wymagane jest użycie dwóch połączeń RNG.


To jest wymagane posiadanie dwóch niezależnych próbek do przekształcenia Boxa-Mullera
ASCII tylko
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.