Einführung
Bei dieser Herausforderung besteht Ihre Aufgabe darin, eine Sammlung einfacher Funktionen zu implementieren, die zusammen eine verwendbare Minibibliothek für einfache Wahrscheinlichkeitsverteilungen bilden. Die folgenden Implementierungen sind akzeptabel, um einige der esoterischeren Sprachen aufzunehmen, die hier gerne verwendet werden:
- Ein Codefragment, das eine Sammlung benannter Funktionen (oder nächstgelegener Entsprechungen) definiert.
- Eine Sammlung von Ausdrücken, die benannte oder anonyme Funktionen (oder nächstgelegene Entsprechungen) ergeben.
- Ein einzelner Ausdruck, der mehrere benannte oder anonyme Funktionen (oder nächstgelegene Entsprechungen) ergibt.
- Eine Sammlung unabhängiger Programme, die Eingaben von der Befehlszeile STDIN oder dem nächstgelegenen Äquivalent und die Ausgabe an STDOUT oder das nächstgelegene Äquivalent übernehmen.
Die Funktionen
Sie müssen die folgenden Funktionen implementieren und bei Bedarf kürzere Namen verwenden.
uniform
Nimmt als Eingabe zwei Gleitkommazahlena
undb
und gibt die Gleichverteilung auf zurück[a,b]
. Sie können davon ausgehena < b
; Der Falla ≥ b
ist undefiniert.blend
nimmt als Eingaben drei WahrscheinlichkeitsverteilungenP
,Q
undR
. Sie gibt eine WahrscheinlichkeitsverteilungS
, die Werte ziehtx
,y
undz
ausP
,Q
undR
, bzw., und Ausbeuten ,y
wennx ≥ 0
, undz
wennx < 0
.over
Nimmt als Eingabe eine Gleitkommazahlf
und eine WahrscheinlichkeitsverteilungP
und gibt die Wahrscheinlichkeit zurück,x ≥ f
die für eine Zufallszahl giltx
, aus der gezogen wirdP
.
Als Referenz over
kann wie folgt definiert werden (im Pseudocode):
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)
Sie können davon ausgehen, dass alle angegebenen Wahrscheinlichkeitsverteilungen over
mit uniform
und erstellt blend
werden und dass das einzige, was ein Benutzer mit einer Wahrscheinlichkeitsverteilung tun wird, darin besteht, sie an blend
oder weiterzuleiten over
. Sie können einen beliebigen Datentyp verwenden, um die Verteilungen darzustellen: Listen mit Zahlen, Zeichenfolgen, benutzerdefinierten Objekten usw. Das einzig Wichtige ist, dass die API ordnungsgemäß funktioniert. Auch Ihre Implementierung muss deterministisch sein, im Sinne der immer die gleiche Leistung für die gleichen Eingaben zurück.
Testfälle
Ihre Ausgabewerte sollten in diesen Testfällen mindestens zwei Stellen nach dem Dezimalpunkt korrekt sein.
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
Antworten:
CJam, 58 Bytes
Dies sind Postfix-Operatoren, die auf dem Stack arbeiten:
2.0 1.0 3.0 U O
isover(2, uniform(1, 3))
.Punktzahl zählen
{[\]}
ist die Funktion selbst,:U;
weist sie dem Namen zuU
und öffnet sie. Im Wesentlichen ist dies nicht Teil der Funktion. Wenn ich also Regel 2 zähle, muss ich nur zählen{[\]}
.B
ist ähnlich definiert.Allerdings
O
ist rekursiv, und wenn ich keinen Namen angeben, gibt es keine Möglichkeit Rekursion. Hier würde ich also gerne den:O;
Teil zählen. Dann ist meine Punktzahl5+5+48=58
insgesamt Bytes.Erläuterung
U
Es werden zwei Argumente angezeigt und ein Paar in umgekehrter Reihenfolge erstellt :a b => [b a]
.B
wirft drei Argumente auf und macht ein Dreifach in gedrehter Reihenfolge :a b c => [b c a]
.O
Die Struktur ist wie folgt:Unterprogramm Γ behandelt gleichmäßige Verteilungen:
Das Unterprogramm Δ behandelt gemischte Verteilungen:
quelle
Ruby, 103
Definiert drei lambdas,
u
,b
, undo
.u
undb
erstellen Sie einfach Arrays mit zwei Elementen bzw. drei Elementen.o
Es wird davon ausgegangen, dass ein Array mit zwei Elementen eine gleichmäßige Verteilung und ein Array mit drei Elementen eine Mischung aus drei Verteilungen ist. Im letzteren Fall ruft es sich rekursiv auf.quelle
MATLAB, 73
Zeit für eine kleine "funktionale Programmierung" in MATLAB. Dies sind 3 anonyme Funktionen. Uniform und Blend werden wie die Beispiele bezeichnet, sollten jedoch für
over
die Argumente ausgetauscht werden. Ich brauche nicht wirklich eineover
seit den ersten beiden Rückgabefunktionen, aber als Formalitätfeval
ist eine Funktion, die eine Funktion aufrufen kann.Jetzt ist das Parsing- und Bewertungssystem von MATLAB, gelinde gesagt, ein wenig wackelig. Sie können eine Funktion, die von einer Funktion zurückgegeben wurde, nicht direkt aufrufen. Stattdessen muss man zuerst das Ergebnis in einer Variablen speichern. Das 4. Beispiel könnte wie folgt gemacht werden:
Es ist jedoch möglich, dies zu umgehen, indem Sie
feval
alle Funktionen aufrufen. Wenn die folgenden Definitionen verwendet werden, können die Beispiele genau so ausgewertet werden, wie sie geschrieben wurden.quelle
Mathematica,
129116 Bytesu
,b
Undo
sinduniform
,blend
undover
respectively.Wrapper über die Standardfunktionen. Ersetzen Sie das\uF3D2
s durch das 3-Byte-Zeichen. Kommt gerade zurück0
und1
für die Fälle 1, 4 und 7.quelle
Python, 146 Bytes
Gleiche Strategie wie die Ruby-Antwort des Histokraten, jedoch in Python. Rekursion ohne Z-Kombinator durchführen (was kostspielig wäre)
x
undy
als Hilfsfunktionen definiert sind, dieover
für Argumenttupel mit 2 bzw. 3 Längen (uniform
bzw.blend
Argumente) ausgewertet werden .Testfälle auf ideone
quelle
Matlab, 104 Bytes
Ich hoffe, dass dies weiterhin gültig ist, da dies nur für Distributionen mit Unterstützung in [-10,10] funktioniert. Dies ist die Voraussetzung für Sprachen ohne Gleitkomma-Unterstützung. Der Unterstützungsvektor und die Genauigkeit können einfach durch Ändern der entsprechenden Zahlen angepasst werden.
u,o,b
ist füruniform,blend,over
. Das PDF wird nur als diskreter Vektor dargestellt. Ich denke, dieser Ansatz kann leicht auf andere Sprachen übertragen werden.Sie können sie testen, wenn Sie diese Funktionen zuerst definieren und dann einfach diesen Code einfügen:
quelle
X
undD
durchMIN_FLOAT
undMAX_FLOAT
(oder wie auch immer Matlab sie nennt) ersetzen können, ist dies ein gültiger Ansatz.realmax
/ verwendenrealmin
, Sie könnten sogar einen Vektor erstellen , der durch alle Gleitkommazahlen geht, wenn Sie über genügend Speicher verfügen.