Wprowadzenie
W tym wyzwaniu Twoim zadaniem jest zaimplementowanie zbioru prostych funkcji, które razem tworzą użyteczną minibibliotekę dla prostych rozkładów prawdopodobieństwa. Aby dostosować się do niektórych bardziej ezoterycznych języków, których ludzie lubią tutaj używać, dopuszczalne są następujące implementacje:
- Fragment kodu definiujący zbiór nazwanych funkcji (lub najbliższych odpowiedników).
- Zbiór wyrażeń, które oceniają na nazwane lub anonimowe funkcje (lub najbliższe odpowiedniki).
- Pojedyncze wyrażenie, które ocenia do kilku nazwanych lub anonimowych funkcji (lub najbliższych odpowiedników).
- Zbiór niezależnych programów, które pobierają dane wejściowe z wiersza poleceń, STDIN lub najbliższego odpowiednika i wysyłają dane do STDOUT lub najbliższego odpowiednika.
Funkcje
Wdrożysz następujące funkcje, w razie potrzeby używając krótszych nazw.
uniform
przyjmuje jako wejście dwóch liczb zmiennoprzecinkowycha
ib
, i zwraca rozkład jednolity na[a,b]
. Możesz założyć, żea < b
; sprawaa ≥ b
jest niezdefiniowana.blend
przyjmuje jako dane wejściowe trzy rozkłady prawdopodobieństwaP
,Q
orazR
. Zwraca rozkład prawdopodobieństwaS
, który opiera się wartośćx
,y
iz
zP
,Q
iR
, odpowiednio, ulegay
, gdyx ≥ 0
iz
jeżelix < 0
.over
przyjmuje jako dane wejściowe liczbę zmiennoprzecinkowąf
i rozkład prawdopodobieństwaP
i zwraca prawdopodobieństwo, które obowiązujex ≥ f
dla losowej liczbyx
wyciągniętej zP
.
W celach informacyjnych over
można zdefiniować w następujący sposób (w pseudokodzie):
over(f, uniform(a, b)):
if f <= a: return 1.0
else if f >= b: return 0.0
else: return (b - f)/(b - a)
over(f, blend(P, Q, R)):
p = over(0.0, P)
return p*over(f, Q) + (1-p)*over(f, R)
Możesz założyć, że wszystkie podane rozkłady prawdopodobieństwa over
są konstruowane przy użyciu uniform
i blend
, i że jedyną rzeczą, którą użytkownik zrobi z rozkładem prawdopodobieństwa, jest karmienie go do blend
lub over
. Możesz użyć dowolnego wygodnego typu danych do przedstawienia dystrybucji: list liczb, ciągów znaków, obiektów niestandardowych itp. Jedyną ważną rzeczą jest to, że interfejs API działa poprawnie. Ponadto twoja implementacja musi być deterministyczna w tym sensie, że zawsze zwraca ten sam wynik dla tych samych danych wejściowych.
Przypadki testowe
Twoje wartości wyjściowe powinny być poprawne do co najmniej dwóch cyfr po przecinku w tych przypadkach testowych.
over(4.356, uniform(-4.873, 2.441)) -> 0.0
over(2.226, uniform(-1.922, 2.664)) -> 0.09550806803314438
over(-4.353, uniform(-7.929, -0.823)) -> 0.49676329862088375
over(-2.491, uniform(-0.340, 6.453)) -> 1.0
over(0.738, blend(uniform(-5.233, 3.384), uniform(2.767, 8.329), uniform(-2.769, 6.497))) -> 0.7701533851999125
over(-3.577, blend(uniform(-3.159, 0.070), blend(blend(uniform(-4.996, 4.851), uniform(-7.516, 1.455), uniform(-0.931, 7.292)), blend(uniform(-5.437, -0.738), uniform(-8.272, -2.316), uniform(-3.225, 1.201)), uniform(3.097, 6.792)), uniform(-8.215, 0.817))) -> 0.4976245638164541
over(3.243, blend(blend(uniform(-4.909, 2.003), uniform(-4.158, 4.622), blend(uniform(0.572, 5.874), uniform(-0.573, 4.716), blend(uniform(-5.279, 3.702), uniform(-6.564, 1.373), uniform(-6.585, 2.802)))), uniform(-3.148, 2.015), blend(uniform(-6.235, -5.629), uniform(-4.647, -1.056), uniform(-0.384, 2.050)))) -> 0.0
over(-3.020, blend(blend(uniform(-0.080, 6.148), blend(uniform(1.691, 6.439), uniform(-7.086, 2.158), uniform(3.423, 6.773)), uniform(-1.780, 2.381)), blend(uniform(-1.754, 1.943), uniform(-0.046, 6.327), blend(uniform(-6.667, 2.543), uniform(0.656, 7.903), blend(uniform(-8.673, 3.639), uniform(-7.606, 1.435), uniform(-5.138, -2.409)))), uniform(-8.008, -0.317))) -> 0.4487803553043079
Odpowiedzi:
CJam, 58 bajtów
Są to operatory Postfix, które działają na stosie:
2.0 1.0 3.0 U O
isover(2, uniform(1, 3))
.Liczba punktów
{[\]}
jest samą funkcją,:U;
przypisuje ją do nazwyU
i wyskakuje. Zasadniczo nie jest to częścią funkcji, więc zgodnie z zasadą liczenia punktów 2 musiałbym tylko liczyć{[\]}
.B
jest zdefiniowany podobnie.Jest jednak
O
rekurencyjne, a jeśli nie podam nazwy, nie ma możliwości ponownego wystąpienia. Więc tutaj chciałbym policzyć tę:O;
część. Zatem mój wynik to5+5+48=58
w sumie bajty.Wyjaśnienie
U
pojawia dwa argumenty i sprawia, że pary w odwrotnej kolejności:a b => [b a]
.B
wyskakuje trzy argumenty i sprawia, że potrójna w obróconym kolejności:a b c => [b c a]
.O
Struktura jest następująca:Podprogram Γ obsługuje jednolite rozkłady:
Podprogram Δ obsługuje mieszane rozkłady:
źródło
Ruby, 103
Definiuje trzy lambdas,
u
,b
, io
.u
ib
po prostu utwórz odpowiednio dwu- i trzyelementowe tablice.o
zakłada, że tablica dwuelementowa jest rozkładem jednolitym, a trzyelementowa jest mieszanką trzech rozkładów. W tym drugim przypadku nazywa się rekurencyjnie.źródło
MATLAB, 73
Czas na trochę „programowania funkcjonalnego” w MATLAB. Są to 3 anonimowe funkcje. Jednolite i mieszane są nazywane tak samo jak w przykładach, ale
over
argumenty powinny zostać zamienione. Tak naprawdę nie potrzebuję,over
odkąd dwie pierwsze funkcje zwracają, ale jako formalnośćfeval
jest funkcją, która może wywoływać funkcję.Teraz system parsowania i oceny MATLAB jest co najmniej trochę chwiejny. Nie pozwala na bezpośrednie wywołanie funkcji, która została zwrócona z funkcji. Zamiast tego należy najpierw zapisać wynik w zmiennej. Czwarty przykład można wykonać w następujący sposób:
Można jednak obejść ten problem,
feval
wywołując wszystkie funkcje. Jeśli zastosowane zostaną następujące definicje, przykłady można ocenić dokładnie tak, jak zostały zapisane.źródło
Mathematica,
129116 bajtówu
,b
Io
touniform
,blend
iover
respectively.Wrapper nad standardowymi funkcjami. Zamień\uF3D2
s na znak 3-bajtowy. Po prostu wraca0
i1
dla przypadków 1, 4 i 7.źródło
Python, 146 bajtów
Ta sama strategia, co odpowiedź Ruby u histokraty, ale w Pythonie. Wykonanie rekurencji bez kombinatora Z (co byłoby kosztowne)
x
iy
są zdefiniowane jako funkcje pomocnicze, które oceniająover
krotki argumentów o długości 2 i 3 (uniform
iblend
argumenty odpowiednio).Testuj przypadki na ideone
źródło
Matlab, 104 bajty
Mam nadzieję, że jest to nadal aktualne, ponieważ działa to tylko w przypadku dystrybucji z obsługą w [-10,10], co jest wymagane dla języków, które nie mają obsługi zmiennoprzecinkowej. Wektor podparcia i dokładność można łatwo regulować, po prostu zmieniając odpowiednie liczby.
u,o,b
jest dlauniform,blend,over
. Plik pdf jest po prostu reprezentowany jako dyskretny wektor. Myślę, że to podejście można łatwo przenieść na inne języki.Możesz je przetestować, jeśli najpierw zdefiniujesz te funkcje, a następnie wkleisz ten kod:
źródło
X
iD
przy pomocyMIN_FLOAT
iMAX_FLOAT
(lub jakkolwiek to nazywa Matlab), jest to prawidłowe podejście.realmax
/realmin
, możesz nawet stworzyć wektor przechodzący przez liczbę zmiennoprzecinkową, jeśli masz wystarczającą ilość pamięci.