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
S
i liczbęN
liczb do zwrócenia. Wyjściem powinna być listaN
liczb zmiennoprzecinkowych, sporządzona z rozkładu normalnego ze średnią 0 i wariancją 1 . Ilekroć twoje zgłoszenie otrzyma to samo ziarnoS
, 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ć
S
i 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).
S
i N
bę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 N
jest 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).
Odpowiedzi:
Dyalog APL, 33 bajty
{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕
Box-Muller :
źródło
⎕rl
na,S+1
ponieważ⎕rl←0
ma specjalne znaczenie.+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.R, 68 bajtów
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,
źródło
f=
(funkcja niekoniecznie musi być nazwana, jeśli funkcje nienazwane są w twoim języku).Error: unexpected '}' in "f=fu...
Poza tym zawsze pojawia się komunikat o błędzie. Czy na pewno otrzymasz te same pierwsze numery, jeśli zadzwoniszf(0,1)
if(0,2)
?Dyalog APL,
4234Jest to funkcja, która przyjmuje
S
za lewy argument iN
za prawy argument.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
: obliczZ0
wartość (sqrt(-2 ln ⍺)×cos(2π⍵)
).źródło
?0
zwraca liczbę zmiennoprzecinkową między 0 a 1.Perl, 67
Box-Muller jak w innych wpisach.
f
porządkuje parametryS, N
.Posługiwać się:
źródło
Java,
164161 bajtówTo pobiera dane wejściowe za pomocą funkcji i dane wyjściowe za pośrednictwem standardowego wyjścia. Wykorzystuje metodę Box-Mullera.
źródło
s=0;s++<n;
->;n-->0;
?Commodore 64 Basic,
767063 bajtówPonieważ 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 docos()
.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ćPOKE
pię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
INPUT
wypowiedzi i że miejsce poTO
jest 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+PgDn
na wypadek, gdybyś się zastanawiał).źródło
Kod maszynowy 80386, 72 bajty
Hexdump kodu:
Oto kod źródłowy (może zostać skompilowany przez Visual Studio):
Tutaj używam generatora liczb losowych Lehmera . Wykorzystuje następujący algorytm:
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
lea
kodowania instrukcji:Składa się z 3 bajtów, jeśli liczby mieszczą się w 1 bajcie.
Wykorzystanie mnożenia i dzielenia
edx
orazeax
ich rejestrów roboczych, dlatego wprowadziłemseed
drugi parametr do funkcji (fastcall
konwencja wywoływania używaedx
do przekazania drugiego parametru). Ponadto przekazywany jest pierwszy parametrecx
, który jest dobrym miejscem do przechowywania licznika: pętla może być zorganizowana w 1 instrukcji!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
001111111
i 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 naebx
:Aby wygenerować dwie liczby losowe, użyłem zagnieżdżonej pętli 2 iteracji. Zorganizowałem to z
xor
:Kod zmiennoprzecinkowy implementuje transformację Box-Muller .
źródło
Haskell, 118
144Przykładowe użycie:
Zwracany jest typ zwracany
random
doFloat
, co powoduje, żerandom
generowanie jednolitego zmiennoprzecinkowego w [0, 1). Od tego czasu jest to prosta formuła box-muller z pewną bezcelową magią do generowania list.źródło
Golflua, 63
70Informacje i instrukcje Golflua.
Zwraca tabelę zawierającą wartości. W przykładzie używam
~T.u( )
, który jest taki sam jakreturn table.unpack( )
w lua.Wiele znaków zostało zapisanych przez ustawienie środowiska funkcji na
M
(akamath
).źródło
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?
Z białą przestrzenią:
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ąput
instrukcji.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 golfowych .
źródło
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()
.Z podziałami linii:
źródło
(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;}
T-SQL, 155 bajtów
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.
źródło
PowerShell, 164 bajty
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.
źródło
Rubinowy, 72 bajty
Dane wejściowe (jako funkcja lambda):
Wynik:
PS: Chciałbym wiedzieć, czy można dalej grać w golfa. Jestem tylko początkującym.
źródło
Matlab, 77
Pierwszym wejściem powinno być
n
drugies
.źródło
Oktawa,
919688 bajtówLub z białymi znakami:
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.źródło
n(0,1)
in(0,2)
otrzymasz różne pierwsze numery, prawda?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.
Ta przestrzeń na początku jest ważna.
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źródło
.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/… ).STATA, 85 bajtów
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.
źródło
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 .
źródło
a
w kodzie, aby wynik był „sprawiedliwy”.)TI-Basic, 74 bajty
Jest
¹
to w rzeczywistości operator odwrotny.źródło
Perl,
150108107 bajtówWykorzystuje metodę Marsaglia Polar . Wywoływany za pomocą f (S, N).
Przeniesiono przypisanie
$a
do obliczeń$c
.107:
Usunięto przechowywanie numerów zapasowych i definicję
$b
.108:
150:
źródło
Swift,
144142Nic mądrego, po prostu widząc, jak działa Swift.
Miałem nadzieję, że mogę użyć (0 ... n) .map {}, ale wydaje się, że kompilator nie rozpoznaje mapy {}, chyba że użyjesz parametru.
źródło
forEach
jeśli nie chcesz zwracanej wartości, i jestem prawie pewien, że_ in
jest ona obowiązkowa/0xffffffff
za btwHaskell , 97 bajtów
Wypróbuj online!
Tylko twoja podstawowa transformacja Boxa-Mullera na nieskończonej liście liczb losowych.
źródło
Python 3 , 118 bajtów
Wypróbuj online!
źródło
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
.Może jest jakiś sposób na zoptymalizowanie formuły. Nie rozumiem, jak wymagane jest użycie dwóch połączeń RNG.
źródło