Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben , die Zufallszahlen aus Intervall [0,1] mit fester Summe ausgibt .n
s
Eingang
n, n≥1
, Anzahl der zu generierenden Zufallszahlen
s, s>=0, s<=n
, Summe der zu generierenden Zahlen
Ausgabe
Ein zufälliges n
Tupel von Gleitkommazahlen mit allen Elementen aus dem Intervall [0,1] und der Summe aller Elemente, die gleich sind s
, wird auf eine bequeme, eindeutige Weise ausgegeben. Alle gültigen n
Tupel müssen innerhalb der Grenzen von Gleitkommazahlen gleich wahrscheinlich sein.
Dies ist gleichbedeutend mit einer gleichmäßigen Abtastung vom Schnittpunkt der Punkte innerhalb des n
Würfels mit den Maßeinheiten und der n-1
eindimensionalen Hyperebene, die durch (s/n, s/n, …, s/n)
den Vektor verläuft und senkrecht zum Vektor verläuft (1, 1, …, 1)
(siehe roter Bereich in Abbildung 1 für drei Beispiele).
Abbildung 1: Die Ebene der gültigen Ausgaben mit n = 3 und den Summen 0,75, 1,75 und 2,75
Beispiele
n=1, s=0.8 → [0.8]
n=3, s=3.0 → [1.0, 1.0, 1.0]
n=2, s=0.0 → [0.0, 0.0]
n=4, s=2.0 → [0.2509075946818119, 0.14887693388076845, 0.9449661625992032, 0.6552493088382167]
n=10, s=9.999999999999 → [0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999]
Regeln
- Ihr Programm sollte auf Ihrem Computer in weniger als einer Sekunde beendet sein, zumindest mit
n≤10
und allen gültigen s. - Wenn Sie möchten, kann Ihr Programm am oberen Ende exklusiv sein, dh
s<n
und die Ausgabenummern aus dem halboffenen Intervall [0,1) (unterbrechen des zweiten Beispiels) - Wenn Ihre Sprache keine Gleitkommazahlen unterstützt, können Sie die Ausgabe mit mindestens zehn Dezimalstellen nach dem Komma fälschen.
- Standard-Regelungslücken sind nicht zulässig, und Standard-Eingabe- / Ausgabemethoden sind zulässig.
- Das ist Code-Golf , also gewinnt der kürzeste Eintrag, gemessen in Bytes.
This is equal to uniformly sampling from the intersection
- ich kann ein Programm sehen, das zufällig nur aus den Ecken dieser Kreuzung auswählt. Wäre das gültig?s==0 or s==3
. Für alle anderen Werte vons
hat die Ebene eine Fläche ungleich Null und Sie müssen einen Punkt auf dieser Ebene gleichmäßig zufällig auswählen.s=2.99999999999, n=3
? Können wir zufällige Reals in Vielfachen von beispielsweise generieren1e-9
?Antworten:
Wolfram Language (Mathematica) ,
92-90BytesProbieren Sie es online!
Code ohne Golf:
Hier ist eine Lösung, die in 55 Bytes funktioniert, aber im Moment (Mathematica Version 12) beschränkt ist auf,
n=1,2,3
weil esRandomPoint
abgelehnt wird, Punkte aus höherdimensionalen Hyperebenen zu zeichnen (in TIOs Version 11.3 schlägt dies ebenfalls fehln=1
). Es könnte jedochn
in Zukunft für höhere Versionen funktionieren :Probieren Sie es online!
Code ohne Golf:
quelle
JavaScript (Node.js) ,
122115 ByteProbieren Sie es online!
quelle
Python 2 ,
144128119 BytesProbieren Sie es online!
quelle
g(4, 2.0)
1.000 Mal gelaufen , um 4.000 Punkte zu bekommen, und die Ergebnisse sehen so aus, als wären sie ziemlich einheitlich.Java 8,
194188196237236 Bytes+49-Bytes (188 → 196 und 196 → 237), um die Geschwindigkeit von Testfällen nahe 1 sowie den Algorithmus im Allgemeinen zu korrigieren.
Probieren Sie es online aus
Erläuterung:
Verwendet den Ansatz in dieser Stackoverflow Antwort , in einer Schleife solange eines des Elements ist noch größer als 1.
Auch wenn
2*s>n
,s
wird in geändert werdenn-s
, und ein Flag gesetzt , um anzuzeigen , sollten wir verwenden ,1-diff
anstattdiff
im Ergebnis-Array (danke für den tipp @soktinpk und @ l4m2 ).quelle
test(10, 9.99);
10, 9.0
nachdem ich denn=10, s=9.999999999999
Testfall bearbeitet habe. Ich bin mir nicht sicher, ob es einen Fix in Java gibt, während ich seine einheitliche Zufälligkeit beibehalte. Muss eine Weile darüber nachdenken. Im Moment bearbeite ich es so, dass es eine Zeitüberschreitung anzeigt.n-s<1
Sie anrufen könnenf(n,n-s)
jede Zahl über und Flip1/2
(dh ersetzenx
mit1-x
tat) wie l4m2. Dies könnte das Problem bei Zahlen in ders
Nähe von lösenn
.s+s>n
stattn-s<1
, aber als ich mir die anderen JavaScript-Antworten ansah, ergab es in der Tat Sinn. Alles ist jetzt behoben, einschließlich eines weiteren Fehlers, der noch vorhanden war. Bytes sind ziemlich gestiegen, aber jetzt funktioniert alles. Arbeitet den Byte-Countdown von hier aus ab. :)JavaScript (Node.js) , 153 Byte
Probieren Sie es online!
quelle
C ++ 11,
284267 Bytes-17 Bytes dank Zacharý
Verwendet C ++ - Zufallsbibliothek, Ausgabe auf der Standardausgabe
Um anzurufen, müssen Sie nur das tun:
Wobei der Schablonenparameter (hier 2) N ist und der tatsächliche Parameter (hier 0,0) S ist
quelle
<z>
und entfernenu
typedef float z;template<int N>void g(z s){z a[N],d=s/N;int i=N;for(;i;)a[--i]=d;std::uniform_real_distribution<z>u(.0,d<.5?d:1-d);std::default_random_engine e;for(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}for(;i;)std::cout<<a[--i]<<' ';}
. Eine neue Zeile muss nicht das Trennzeichen zwischen Elementen seind
vollständig durch eine Änderungd=s/N
aufs/=N
Vorschlagen die zweite Schleife Nachbearbeitungfor(z c;i<N;a[++i%N]-=c)a[i]+=c=u(e);
stattfor(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}
( man beachte die hinzugefügt%N
, um das Programm berechnet die erste Zahl richtig zu machen)Sauber ,
221201 BytesClean, Code-Golf oder Zufallszahlen. Suche dir zwei aus.
Probieren Sie es online!
Teilfunktionsliteral
:: (Int Real -> [Real])
. Erzeugt nur einmal pro Sekunde neue Ergebnisse.Genauigkeit bis zu mindestens 10 Dezimalstellen.
quelle
R , 99 Bytes (mit
gtools
Paket)Probieren Sie es online!
quelle
C,
132127125118110107 Bytes-2 Bytes dank @ceilingcat
Probieren Sie es online!
quelle
[0,1]
und ihre gemeinsame Verteilung ist nicht einheitlich.n=4
, werden Wertes=3.23
unds=0.89
Ausgaben außerhalb des Bereichs ausgegeben. Genauer gesagt, die Verteilung vonX-s/n
sollte davon abhängens
, tut es aber nicht.Haskell ,
122217208 BytesProbieren Sie es online!
Manchmal sind die Antworten aufgrund von Gleitkommafehlern etwas falsch. Wenn es ein Problem ist, kann ich es zu einem Preis von 1 Byte beheben. Ich bin mir auch nicht sicher, wie einheitlich das ist (ziemlich sicher, dass es in Ordnung ist, aber ich bin nicht so gut in so etwas), also beschreibe ich meinen Algorithmus.
Die Grundidee ist, eine Zahl zu generieren, sie
x
dann zu subtrahierens
und so lange zu wiederholen, bis wirn
Elemente haben, die wir dann mischen. Ich generierex
mit einer Obergrenze von 1 oders
(je nachdem, welcher Wert kleiner ist) und einer Untergrenze vons-n+1
oder 0 (je nachdem, welcher Wert größer ist). Diese Untergrenze ist vorhanden, sodass sie bei der nächsten Iterations
immer noch kleiner oder gleich istn
(Herleitung:s-x<=n-1
->s<=n-1+x
->s-(n-1)<=x
->s-n+1<=x
).EDIT: Danke an @ michi7x7 für den Hinweis auf einen Fehler in meiner Uniformität. Ich glaube, ich habe es durch Mischen behoben, aber lass es mich wissen, wenn es ein anderes Problem gibt
EDIT2: Verbesserte Byteanzahl plus feste Typeinschränkung
quelle
Haskell , 188 Bytes
Ungolfed:
Probieren Sie es online!
quelle